##// END OF EJS Templates
Merge pull request #11271 from luzpaz/misc-typo-and-whitespaces...
Matthias Bussonnier -
r24495:0de2f49c merge
parent child Browse files
Show More
@@ -1,161 +1,161 b''
1 """Compiler tools with improved interactive support.
1 """Compiler tools with improved interactive support.
2
2
3 Provides compilation machinery similar to codeop, but with caching support so
3 Provides compilation machinery similar to codeop, but with caching support so
4 we can provide interactive tracebacks.
4 we can provide interactive tracebacks.
5
5
6 Authors
6 Authors
7 -------
7 -------
8 * Robert Kern
8 * Robert Kern
9 * Fernando Perez
9 * Fernando Perez
10 * Thomas Kluyver
10 * Thomas Kluyver
11 """
11 """
12
12
13 # Note: though it might be more natural to name this module 'compiler', that
13 # Note: though it might be more natural to name this module 'compiler', that
14 # name is in the stdlib and name collisions with the stdlib tend to produce
14 # name is in the stdlib and name collisions with the stdlib tend to produce
15 # weird problems (often with third-party tools).
15 # weird problems (often with third-party tools).
16
16
17 #-----------------------------------------------------------------------------
17 #-----------------------------------------------------------------------------
18 # Copyright (C) 2010-2011 The IPython Development Team.
18 # Copyright (C) 2010-2011 The IPython Development Team.
19 #
19 #
20 # Distributed under the terms of the BSD License.
20 # Distributed under the terms of the BSD License.
21 #
21 #
22 # The full license is in the file COPYING.txt, distributed with this software.
22 # The full license is in the file COPYING.txt, distributed with this software.
23 #-----------------------------------------------------------------------------
23 #-----------------------------------------------------------------------------
24
24
25 #-----------------------------------------------------------------------------
25 #-----------------------------------------------------------------------------
26 # Imports
26 # Imports
27 #-----------------------------------------------------------------------------
27 #-----------------------------------------------------------------------------
28
28
29 # Stdlib imports
29 # Stdlib imports
30 import __future__
30 import __future__
31 from ast import PyCF_ONLY_AST
31 from ast import PyCF_ONLY_AST
32 import codeop
32 import codeop
33 import functools
33 import functools
34 import hashlib
34 import hashlib
35 import linecache
35 import linecache
36 import operator
36 import operator
37 import time
37 import time
38
38
39 #-----------------------------------------------------------------------------
39 #-----------------------------------------------------------------------------
40 # Constants
40 # Constants
41 #-----------------------------------------------------------------------------
41 #-----------------------------------------------------------------------------
42
42
43 # Roughtly equal to PyCF_MASK | PyCF_MASK_OBSOLETE as defined in pythonrun.h,
43 # Roughly equal to PyCF_MASK | PyCF_MASK_OBSOLETE as defined in pythonrun.h,
44 # this is used as a bitmask to extract future-related code flags.
44 # this is used as a bitmask to extract future-related code flags.
45 PyCF_MASK = functools.reduce(operator.or_,
45 PyCF_MASK = functools.reduce(operator.or_,
46 (getattr(__future__, fname).compiler_flag
46 (getattr(__future__, fname).compiler_flag
47 for fname in __future__.all_feature_names))
47 for fname in __future__.all_feature_names))
48
48
49 #-----------------------------------------------------------------------------
49 #-----------------------------------------------------------------------------
50 # Local utilities
50 # Local utilities
51 #-----------------------------------------------------------------------------
51 #-----------------------------------------------------------------------------
52
52
53 def code_name(code, number=0):
53 def code_name(code, number=0):
54 """ Compute a (probably) unique name for code for caching.
54 """ Compute a (probably) unique name for code for caching.
55
55
56 This now expects code to be unicode.
56 This now expects code to be unicode.
57 """
57 """
58 hash_digest = hashlib.sha1(code.encode("utf-8")).hexdigest()
58 hash_digest = hashlib.sha1(code.encode("utf-8")).hexdigest()
59 # Include the number and 12 characters of the hash in the name. It's
59 # Include the number and 12 characters of the hash in the name. It's
60 # pretty much impossible that in a single session we'll have collisions
60 # pretty much impossible that in a single session we'll have collisions
61 # even with truncated hashes, and the full one makes tracebacks too long
61 # even with truncated hashes, and the full one makes tracebacks too long
62 return '<ipython-input-{0}-{1}>'.format(number, hash_digest[:12])
62 return '<ipython-input-{0}-{1}>'.format(number, hash_digest[:12])
63
63
64 #-----------------------------------------------------------------------------
64 #-----------------------------------------------------------------------------
65 # Classes and functions
65 # Classes and functions
66 #-----------------------------------------------------------------------------
66 #-----------------------------------------------------------------------------
67
67
68 class CachingCompiler(codeop.Compile):
68 class CachingCompiler(codeop.Compile):
69 """A compiler that caches code compiled from interactive statements.
69 """A compiler that caches code compiled from interactive statements.
70 """
70 """
71
71
72 def __init__(self):
72 def __init__(self):
73 codeop.Compile.__init__(self)
73 codeop.Compile.__init__(self)
74
74
75 # This is ugly, but it must be done this way to allow multiple
75 # This is ugly, but it must be done this way to allow multiple
76 # simultaneous ipython instances to coexist. Since Python itself
76 # simultaneous ipython instances to coexist. Since Python itself
77 # directly accesses the data structures in the linecache module, and
77 # directly accesses the data structures in the linecache module, and
78 # the cache therein is global, we must work with that data structure.
78 # the cache therein is global, we must work with that data structure.
79 # We must hold a reference to the original checkcache routine and call
79 # We must hold a reference to the original checkcache routine and call
80 # that in our own check_cache() below, but the special IPython cache
80 # that in our own check_cache() below, but the special IPython cache
81 # must also be shared by all IPython instances. If we were to hold
81 # must also be shared by all IPython instances. If we were to hold
82 # separate caches (one in each CachingCompiler instance), any call made
82 # separate caches (one in each CachingCompiler instance), any call made
83 # by Python itself to linecache.checkcache() would obliterate the
83 # by Python itself to linecache.checkcache() would obliterate the
84 # cached data from the other IPython instances.
84 # cached data from the other IPython instances.
85 if not hasattr(linecache, '_ipython_cache'):
85 if not hasattr(linecache, '_ipython_cache'):
86 linecache._ipython_cache = {}
86 linecache._ipython_cache = {}
87 if not hasattr(linecache, '_checkcache_ori'):
87 if not hasattr(linecache, '_checkcache_ori'):
88 linecache._checkcache_ori = linecache.checkcache
88 linecache._checkcache_ori = linecache.checkcache
89 # Now, we must monkeypatch the linecache directly so that parts of the
89 # Now, we must monkeypatch the linecache directly so that parts of the
90 # stdlib that call it outside our control go through our codepath
90 # stdlib that call it outside our control go through our codepath
91 # (otherwise we'd lose our tracebacks).
91 # (otherwise we'd lose our tracebacks).
92 linecache.checkcache = check_linecache_ipython
92 linecache.checkcache = check_linecache_ipython
93
93
94
94
95 def _fix_module_ds(self, module):
95 def _fix_module_ds(self, module):
96 """
96 """
97 Starting in python 3.7 the AST for mule have changed, and if
97 Starting in python 3.7 the AST for mule have changed, and if
98 the first expressions encountered is a string it is attached to the
98 the first expressions encountered is a string it is attached to the
99 `docstring` attribute of the `Module` ast node.
99 `docstring` attribute of the `Module` ast node.
100
100
101 This breaks IPython, as if this string is the only expression, IPython
101 This breaks IPython, as if this string is the only expression, IPython
102 will not return it as the result of the current cell.
102 will not return it as the result of the current cell.
103 """
103 """
104 from ast import Str, Expr, Module, fix_missing_locations
104 from ast import Str, Expr, Module, fix_missing_locations
105 docstring = getattr(module, 'docstring', None)
105 docstring = getattr(module, 'docstring', None)
106 if not docstring:
106 if not docstring:
107 return module
107 return module
108 new_body=[Expr(Str(docstring, lineno=1, col_offset=0), lineno=1, col_offset=0)]
108 new_body=[Expr(Str(docstring, lineno=1, col_offset=0), lineno=1, col_offset=0)]
109 new_body.extend(module.body)
109 new_body.extend(module.body)
110 return fix_missing_locations(Module(new_body))
110 return fix_missing_locations(Module(new_body))
111
111
112 def ast_parse(self, source, filename='<unknown>', symbol='exec'):
112 def ast_parse(self, source, filename='<unknown>', symbol='exec'):
113 """Parse code to an AST with the current compiler flags active.
113 """Parse code to an AST with the current compiler flags active.
114
114
115 Arguments are exactly the same as ast.parse (in the standard library),
115 Arguments are exactly the same as ast.parse (in the standard library),
116 and are passed to the built-in compile function."""
116 and are passed to the built-in compile function."""
117 return self._fix_module_ds(compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1))
117 return self._fix_module_ds(compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1))
118
118
119 def reset_compiler_flags(self):
119 def reset_compiler_flags(self):
120 """Reset compiler flags to default state."""
120 """Reset compiler flags to default state."""
121 # This value is copied from codeop.Compile.__init__, so if that ever
121 # This value is copied from codeop.Compile.__init__, so if that ever
122 # changes, it will need to be updated.
122 # changes, it will need to be updated.
123 self.flags = codeop.PyCF_DONT_IMPLY_DEDENT
123 self.flags = codeop.PyCF_DONT_IMPLY_DEDENT
124
124
125 @property
125 @property
126 def compiler_flags(self):
126 def compiler_flags(self):
127 """Flags currently active in the compilation process.
127 """Flags currently active in the compilation process.
128 """
128 """
129 return self.flags
129 return self.flags
130
130
131 def cache(self, code, number=0):
131 def cache(self, code, number=0):
132 """Make a name for a block of code, and cache the code.
132 """Make a name for a block of code, and cache the code.
133
133
134 Parameters
134 Parameters
135 ----------
135 ----------
136 code : str
136 code : str
137 The Python source code to cache.
137 The Python source code to cache.
138 number : int
138 number : int
139 A number which forms part of the code's name. Used for the execution
139 A number which forms part of the code's name. Used for the execution
140 counter.
140 counter.
141
141
142 Returns
142 Returns
143 -------
143 -------
144 The name of the cached code (as a string). Pass this as the filename
144 The name of the cached code (as a string). Pass this as the filename
145 argument to compilation, so that tracebacks are correctly hooked up.
145 argument to compilation, so that tracebacks are correctly hooked up.
146 """
146 """
147 name = code_name(code, number)
147 name = code_name(code, number)
148 entry = (len(code), time.time(),
148 entry = (len(code), time.time(),
149 [line+'\n' for line in code.splitlines()], name)
149 [line+'\n' for line in code.splitlines()], name)
150 linecache.cache[name] = entry
150 linecache.cache[name] = entry
151 linecache._ipython_cache[name] = entry
151 linecache._ipython_cache[name] = entry
152 return name
152 return name
153
153
154 def check_linecache_ipython(*args):
154 def check_linecache_ipython(*args):
155 """Call linecache.checkcache() safely protecting our cached values.
155 """Call linecache.checkcache() safely protecting our cached values.
156 """
156 """
157 # First call the original checkcache as intended
157 # First call the original checkcache as intended
158 linecache._checkcache_ori(*args)
158 linecache._checkcache_ori(*args)
159 # Then, update back the cache with our data, so that tracebacks related
159 # Then, update back the cache with our data, so that tracebacks related
160 # to our compiled codes can be produced.
160 # to our compiled codes can be produced.
161 linecache.cache.update(linecache._ipython_cache)
161 linecache.cache.update(linecache._ipython_cache)
@@ -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 IPython.core.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 IPython.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, shotdown 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 IPython.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,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 IPython.core.autocall import IPyAutocall
16 from traitlets.config.configurable import Configurable
16 from traitlets.config.configurable import Configurable
17 from IPython.core.inputsplitter import (
17 from IPython.core.inputsplitter 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 IPython.core.macro import Macro
24 from IPython.core.splitinput import LineInfo
24 from IPython.core.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 iplementation 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,871 +1,871 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 Python advanced pretty printer. This pretty printer is intended to
3 Python advanced pretty printer. This pretty printer is intended to
4 replace the old `pprint` python module which does not allow developers
4 replace the old `pprint` python module which does not allow developers
5 to provide their own pretty print callbacks.
5 to provide their own pretty print callbacks.
6
6
7 This module is based on ruby's `prettyprint.rb` library by `Tanaka Akira`.
7 This module is based on ruby's `prettyprint.rb` library by `Tanaka Akira`.
8
8
9
9
10 Example Usage
10 Example Usage
11 -------------
11 -------------
12
12
13 To directly print the representation of an object use `pprint`::
13 To directly print the representation of an object use `pprint`::
14
14
15 from pretty import pprint
15 from pretty import pprint
16 pprint(complex_object)
16 pprint(complex_object)
17
17
18 To get a string of the output use `pretty`::
18 To get a string of the output use `pretty`::
19
19
20 from pretty import pretty
20 from pretty import pretty
21 string = pretty(complex_object)
21 string = pretty(complex_object)
22
22
23
23
24 Extending
24 Extending
25 ---------
25 ---------
26
26
27 The pretty library allows developers to add pretty printing rules for their
27 The pretty library allows developers to add pretty printing rules for their
28 own objects. This process is straightforward. All you have to do is to
28 own objects. This process is straightforward. All you have to do is to
29 add a `_repr_pretty_` method to your object and call the methods on the
29 add a `_repr_pretty_` method to your object and call the methods on the
30 pretty printer passed::
30 pretty printer passed::
31
31
32 class MyObject(object):
32 class MyObject(object):
33
33
34 def _repr_pretty_(self, p, cycle):
34 def _repr_pretty_(self, p, cycle):
35 ...
35 ...
36
36
37 Here is an example implementation of a `_repr_pretty_` method for a list
37 Here is an example implementation of a `_repr_pretty_` method for a list
38 subclass::
38 subclass::
39
39
40 class MyList(list):
40 class MyList(list):
41
41
42 def _repr_pretty_(self, p, cycle):
42 def _repr_pretty_(self, p, cycle):
43 if cycle:
43 if cycle:
44 p.text('MyList(...)')
44 p.text('MyList(...)')
45 else:
45 else:
46 with p.group(8, 'MyList([', '])'):
46 with p.group(8, 'MyList([', '])'):
47 for idx, item in enumerate(self):
47 for idx, item in enumerate(self):
48 if idx:
48 if idx:
49 p.text(',')
49 p.text(',')
50 p.breakable()
50 p.breakable()
51 p.pretty(item)
51 p.pretty(item)
52
52
53 The `cycle` parameter is `True` if pretty detected a cycle. You *have* to
53 The `cycle` parameter is `True` if pretty detected a cycle. You *have* to
54 react to that or the result is an infinite loop. `p.text()` just adds
54 react to that or the result is an infinite loop. `p.text()` just adds
55 non breaking text to the output, `p.breakable()` either adds a whitespace
55 non breaking text to the output, `p.breakable()` either adds a whitespace
56 or breaks here. If you pass it an argument it's used instead of the
56 or breaks here. If you pass it an argument it's used instead of the
57 default space. `p.pretty` prettyprints another object using the pretty print
57 default space. `p.pretty` prettyprints another object using the pretty print
58 method.
58 method.
59
59
60 The first parameter to the `group` function specifies the extra indentation
60 The first parameter to the `group` function specifies the extra indentation
61 of the next line. In this example the next item will either be on the same
61 of the next line. In this example the next item will either be on the same
62 line (if the items are short enough) or aligned with the right edge of the
62 line (if the items are short enough) or aligned with the right edge of the
63 opening bracket of `MyList`.
63 opening bracket of `MyList`.
64
64
65 If you just want to indent something you can use the group function
65 If you just want to indent something you can use the group function
66 without open / close parameters. You can also use this code::
66 without open / close parameters. You can also use this code::
67
67
68 with p.indent(2):
68 with p.indent(2):
69 ...
69 ...
70
70
71 Inheritance diagram:
71 Inheritance diagram:
72
72
73 .. inheritance-diagram:: IPython.lib.pretty
73 .. inheritance-diagram:: IPython.lib.pretty
74 :parts: 3
74 :parts: 3
75
75
76 :copyright: 2007 by Armin Ronacher.
76 :copyright: 2007 by Armin Ronacher.
77 Portions (c) 2009 by Robert Kern.
77 Portions (c) 2009 by Robert Kern.
78 :license: BSD License.
78 :license: BSD License.
79 """
79 """
80
80
81 from contextlib import contextmanager
81 from contextlib import contextmanager
82 import datetime
82 import datetime
83 import os
83 import os
84 import re
84 import re
85 import sys
85 import sys
86 import types
86 import types
87 from collections import deque
87 from collections import deque
88 from inspect import signature
88 from inspect import signature
89 from io import StringIO
89 from io import StringIO
90 from warnings import warn
90 from warnings import warn
91
91
92 from IPython.utils.decorators import undoc
92 from IPython.utils.decorators import undoc
93 from IPython.utils.py3compat import PYPY
93 from IPython.utils.py3compat import PYPY
94
94
95 __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter',
95 __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter',
96 'for_type', 'for_type_by_name']
96 'for_type', 'for_type_by_name']
97
97
98
98
99 MAX_SEQ_LENGTH = 1000
99 MAX_SEQ_LENGTH = 1000
100 # The language spec says that dicts preserve order from 3.7, but CPython
100 # The language spec says that dicts preserve order from 3.7, but CPython
101 # does so from 3.6, so it seems likely that people will expect that.
101 # does so from 3.6, so it seems likely that people will expect that.
102 DICT_IS_ORDERED = sys.version_info >= (3, 6)
102 DICT_IS_ORDERED = sys.version_info >= (3, 6)
103 _re_pattern_type = type(re.compile(''))
103 _re_pattern_type = type(re.compile(''))
104
104
105 def _safe_getattr(obj, attr, default=None):
105 def _safe_getattr(obj, attr, default=None):
106 """Safe version of getattr.
106 """Safe version of getattr.
107
107
108 Same as getattr, but will return ``default`` on any Exception,
108 Same as getattr, but will return ``default`` on any Exception,
109 rather than raising.
109 rather than raising.
110 """
110 """
111 try:
111 try:
112 return getattr(obj, attr, default)
112 return getattr(obj, attr, default)
113 except Exception:
113 except Exception:
114 return default
114 return default
115
115
116 @undoc
116 @undoc
117 class CUnicodeIO(StringIO):
117 class CUnicodeIO(StringIO):
118 def __init__(self, *args, **kwargs):
118 def __init__(self, *args, **kwargs):
119 super().__init__(*args, **kwargs)
119 super().__init__(*args, **kwargs)
120 warn(("CUnicodeIO is deprecated since IPython 6.0. "
120 warn(("CUnicodeIO is deprecated since IPython 6.0. "
121 "Please use io.StringIO instead."),
121 "Please use io.StringIO instead."),
122 DeprecationWarning, stacklevel=2)
122 DeprecationWarning, stacklevel=2)
123
123
124 def _sorted_for_pprint(items):
124 def _sorted_for_pprint(items):
125 """
125 """
126 Sort the given items for pretty printing. Since some predictable
126 Sort the given items for pretty printing. Since some predictable
127 sorting is better than no sorting at all, we sort on the string
127 sorting is better than no sorting at all, we sort on the string
128 representation if normal sorting fails.
128 representation if normal sorting fails.
129 """
129 """
130 items = list(items)
130 items = list(items)
131 try:
131 try:
132 return sorted(items)
132 return sorted(items)
133 except Exception:
133 except Exception:
134 try:
134 try:
135 return sorted(items, key=str)
135 return sorted(items, key=str)
136 except Exception:
136 except Exception:
137 return items
137 return items
138
138
139 def pretty(obj, verbose=False, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
139 def pretty(obj, verbose=False, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
140 """
140 """
141 Pretty print the object's representation.
141 Pretty print the object's representation.
142 """
142 """
143 stream = StringIO()
143 stream = StringIO()
144 printer = RepresentationPrinter(stream, verbose, max_width, newline, max_seq_length=max_seq_length)
144 printer = RepresentationPrinter(stream, verbose, max_width, newline, max_seq_length=max_seq_length)
145 printer.pretty(obj)
145 printer.pretty(obj)
146 printer.flush()
146 printer.flush()
147 return stream.getvalue()
147 return stream.getvalue()
148
148
149
149
150 def pprint(obj, verbose=False, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
150 def pprint(obj, verbose=False, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
151 """
151 """
152 Like `pretty` but print to stdout.
152 Like `pretty` but print to stdout.
153 """
153 """
154 printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline, max_seq_length=max_seq_length)
154 printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline, max_seq_length=max_seq_length)
155 printer.pretty(obj)
155 printer.pretty(obj)
156 printer.flush()
156 printer.flush()
157 sys.stdout.write(newline)
157 sys.stdout.write(newline)
158 sys.stdout.flush()
158 sys.stdout.flush()
159
159
160 class _PrettyPrinterBase(object):
160 class _PrettyPrinterBase(object):
161
161
162 @contextmanager
162 @contextmanager
163 def indent(self, indent):
163 def indent(self, indent):
164 """with statement support for indenting/dedenting."""
164 """with statement support for indenting/dedenting."""
165 self.indentation += indent
165 self.indentation += indent
166 try:
166 try:
167 yield
167 yield
168 finally:
168 finally:
169 self.indentation -= indent
169 self.indentation -= indent
170
170
171 @contextmanager
171 @contextmanager
172 def group(self, indent=0, open='', close=''):
172 def group(self, indent=0, open='', close=''):
173 """like begin_group / end_group but for the with statement."""
173 """like begin_group / end_group but for the with statement."""
174 self.begin_group(indent, open)
174 self.begin_group(indent, open)
175 try:
175 try:
176 yield
176 yield
177 finally:
177 finally:
178 self.end_group(indent, close)
178 self.end_group(indent, close)
179
179
180 class PrettyPrinter(_PrettyPrinterBase):
180 class PrettyPrinter(_PrettyPrinterBase):
181 """
181 """
182 Baseclass for the `RepresentationPrinter` prettyprinter that is used to
182 Baseclass for the `RepresentationPrinter` prettyprinter that is used to
183 generate pretty reprs of objects. Contrary to the `RepresentationPrinter`
183 generate pretty reprs of objects. Contrary to the `RepresentationPrinter`
184 this printer knows nothing about the default pprinters or the `_repr_pretty_`
184 this printer knows nothing about the default pprinters or the `_repr_pretty_`
185 callback method.
185 callback method.
186 """
186 """
187
187
188 def __init__(self, output, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
188 def __init__(self, output, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
189 self.output = output
189 self.output = output
190 self.max_width = max_width
190 self.max_width = max_width
191 self.newline = newline
191 self.newline = newline
192 self.max_seq_length = max_seq_length
192 self.max_seq_length = max_seq_length
193 self.output_width = 0
193 self.output_width = 0
194 self.buffer_width = 0
194 self.buffer_width = 0
195 self.buffer = deque()
195 self.buffer = deque()
196
196
197 root_group = Group(0)
197 root_group = Group(0)
198 self.group_stack = [root_group]
198 self.group_stack = [root_group]
199 self.group_queue = GroupQueue(root_group)
199 self.group_queue = GroupQueue(root_group)
200 self.indentation = 0
200 self.indentation = 0
201
201
202 def _break_outer_groups(self):
202 def _break_outer_groups(self):
203 while self.max_width < self.output_width + self.buffer_width:
203 while self.max_width < self.output_width + self.buffer_width:
204 group = self.group_queue.deq()
204 group = self.group_queue.deq()
205 if not group:
205 if not group:
206 return
206 return
207 while group.breakables:
207 while group.breakables:
208 x = self.buffer.popleft()
208 x = self.buffer.popleft()
209 self.output_width = x.output(self.output, self.output_width)
209 self.output_width = x.output(self.output, self.output_width)
210 self.buffer_width -= x.width
210 self.buffer_width -= x.width
211 while self.buffer and isinstance(self.buffer[0], Text):
211 while self.buffer and isinstance(self.buffer[0], Text):
212 x = self.buffer.popleft()
212 x = self.buffer.popleft()
213 self.output_width = x.output(self.output, self.output_width)
213 self.output_width = x.output(self.output, self.output_width)
214 self.buffer_width -= x.width
214 self.buffer_width -= x.width
215
215
216 def text(self, obj):
216 def text(self, obj):
217 """Add literal text to the output."""
217 """Add literal text to the output."""
218 width = len(obj)
218 width = len(obj)
219 if self.buffer:
219 if self.buffer:
220 text = self.buffer[-1]
220 text = self.buffer[-1]
221 if not isinstance(text, Text):
221 if not isinstance(text, Text):
222 text = Text()
222 text = Text()
223 self.buffer.append(text)
223 self.buffer.append(text)
224 text.add(obj, width)
224 text.add(obj, width)
225 self.buffer_width += width
225 self.buffer_width += width
226 self._break_outer_groups()
226 self._break_outer_groups()
227 else:
227 else:
228 self.output.write(obj)
228 self.output.write(obj)
229 self.output_width += width
229 self.output_width += width
230
230
231 def breakable(self, sep=' '):
231 def breakable(self, sep=' '):
232 """
232 """
233 Add a breakable separator to the output. This does not mean that it
233 Add a breakable separator to the output. This does not mean that it
234 will automatically break here. If no breaking on this position takes
234 will automatically break here. If no breaking on this position takes
235 place the `sep` is inserted which default to one space.
235 place the `sep` is inserted which default to one space.
236 """
236 """
237 width = len(sep)
237 width = len(sep)
238 group = self.group_stack[-1]
238 group = self.group_stack[-1]
239 if group.want_break:
239 if group.want_break:
240 self.flush()
240 self.flush()
241 self.output.write(self.newline)
241 self.output.write(self.newline)
242 self.output.write(' ' * self.indentation)
242 self.output.write(' ' * self.indentation)
243 self.output_width = self.indentation
243 self.output_width = self.indentation
244 self.buffer_width = 0
244 self.buffer_width = 0
245 else:
245 else:
246 self.buffer.append(Breakable(sep, width, self))
246 self.buffer.append(Breakable(sep, width, self))
247 self.buffer_width += width
247 self.buffer_width += width
248 self._break_outer_groups()
248 self._break_outer_groups()
249
249
250 def break_(self):
250 def break_(self):
251 """
251 """
252 Explicitly insert a newline into the output, maintaining correct indentation.
252 Explicitly insert a newline into the output, maintaining correct indentation.
253 """
253 """
254 self.flush()
254 self.flush()
255 self.output.write(self.newline)
255 self.output.write(self.newline)
256 self.output.write(' ' * self.indentation)
256 self.output.write(' ' * self.indentation)
257 self.output_width = self.indentation
257 self.output_width = self.indentation
258 self.buffer_width = 0
258 self.buffer_width = 0
259
259
260
260
261 def begin_group(self, indent=0, open=''):
261 def begin_group(self, indent=0, open=''):
262 """
262 """
263 Begin a group. If you want support for python < 2.5 which doesn't has
263 Begin a group. If you want support for python < 2.5 which doesn't has
264 the with statement this is the preferred way:
264 the with statement this is the preferred way:
265
265
266 p.begin_group(1, '{')
266 p.begin_group(1, '{')
267 ...
267 ...
268 p.end_group(1, '}')
268 p.end_group(1, '}')
269
269
270 The python 2.5 expression would be this:
270 The python 2.5 expression would be this:
271
271
272 with p.group(1, '{', '}'):
272 with p.group(1, '{', '}'):
273 ...
273 ...
274
274
275 The first parameter specifies the indentation for the next line (usually
275 The first parameter specifies the indentation for the next line (usually
276 the width of the opening text), the second the opening text. All
276 the width of the opening text), the second the opening text. All
277 parameters are optional.
277 parameters are optional.
278 """
278 """
279 if open:
279 if open:
280 self.text(open)
280 self.text(open)
281 group = Group(self.group_stack[-1].depth + 1)
281 group = Group(self.group_stack[-1].depth + 1)
282 self.group_stack.append(group)
282 self.group_stack.append(group)
283 self.group_queue.enq(group)
283 self.group_queue.enq(group)
284 self.indentation += indent
284 self.indentation += indent
285
285
286 def _enumerate(self, seq):
286 def _enumerate(self, seq):
287 """like enumerate, but with an upper limit on the number of items"""
287 """like enumerate, but with an upper limit on the number of items"""
288 for idx, x in enumerate(seq):
288 for idx, x in enumerate(seq):
289 if self.max_seq_length and idx >= self.max_seq_length:
289 if self.max_seq_length and idx >= self.max_seq_length:
290 self.text(',')
290 self.text(',')
291 self.breakable()
291 self.breakable()
292 self.text('...')
292 self.text('...')
293 return
293 return
294 yield idx, x
294 yield idx, x
295
295
296 def end_group(self, dedent=0, close=''):
296 def end_group(self, dedent=0, close=''):
297 """End a group. See `begin_group` for more details."""
297 """End a group. See `begin_group` for more details."""
298 self.indentation -= dedent
298 self.indentation -= dedent
299 group = self.group_stack.pop()
299 group = self.group_stack.pop()
300 if not group.breakables:
300 if not group.breakables:
301 self.group_queue.remove(group)
301 self.group_queue.remove(group)
302 if close:
302 if close:
303 self.text(close)
303 self.text(close)
304
304
305 def flush(self):
305 def flush(self):
306 """Flush data that is left in the buffer."""
306 """Flush data that is left in the buffer."""
307 for data in self.buffer:
307 for data in self.buffer:
308 self.output_width += data.output(self.output, self.output_width)
308 self.output_width += data.output(self.output, self.output_width)
309 self.buffer.clear()
309 self.buffer.clear()
310 self.buffer_width = 0
310 self.buffer_width = 0
311
311
312
312
313 def _get_mro(obj_class):
313 def _get_mro(obj_class):
314 """ Get a reasonable method resolution order of a class and its superclasses
314 """ Get a reasonable method resolution order of a class and its superclasses
315 for both old-style and new-style classes.
315 for both old-style and new-style classes.
316 """
316 """
317 if not hasattr(obj_class, '__mro__'):
317 if not hasattr(obj_class, '__mro__'):
318 # Old-style class. Mix in object to make a fake new-style class.
318 # Old-style class. Mix in object to make a fake new-style class.
319 try:
319 try:
320 obj_class = type(obj_class.__name__, (obj_class, object), {})
320 obj_class = type(obj_class.__name__, (obj_class, object), {})
321 except TypeError:
321 except TypeError:
322 # Old-style extension type that does not descend from object.
322 # Old-style extension type that does not descend from object.
323 # FIXME: try to construct a more thorough MRO.
323 # FIXME: try to construct a more thorough MRO.
324 mro = [obj_class]
324 mro = [obj_class]
325 else:
325 else:
326 mro = obj_class.__mro__[1:-1]
326 mro = obj_class.__mro__[1:-1]
327 else:
327 else:
328 mro = obj_class.__mro__
328 mro = obj_class.__mro__
329 return mro
329 return mro
330
330
331
331
332 class RepresentationPrinter(PrettyPrinter):
332 class RepresentationPrinter(PrettyPrinter):
333 """
333 """
334 Special pretty printer that has a `pretty` method that calls the pretty
334 Special pretty printer that has a `pretty` method that calls the pretty
335 printer for a python object.
335 printer for a python object.
336
336
337 This class stores processing data on `self` so you must *never* use
337 This class stores processing data on `self` so you must *never* use
338 this class in a threaded environment. Always lock it or reinstanciate
338 this class in a threaded environment. Always lock it or reinstanciate
339 it.
339 it.
340
340
341 Instances also have a verbose flag callbacks can access to control their
341 Instances also have a verbose flag callbacks can access to control their
342 output. For example the default instance repr prints all attributes and
342 output. For example the default instance repr prints all attributes and
343 methods that are not prefixed by an underscore if the printer is in
343 methods that are not prefixed by an underscore if the printer is in
344 verbose mode.
344 verbose mode.
345 """
345 """
346
346
347 def __init__(self, output, verbose=False, max_width=79, newline='\n',
347 def __init__(self, output, verbose=False, max_width=79, newline='\n',
348 singleton_pprinters=None, type_pprinters=None, deferred_pprinters=None,
348 singleton_pprinters=None, type_pprinters=None, deferred_pprinters=None,
349 max_seq_length=MAX_SEQ_LENGTH):
349 max_seq_length=MAX_SEQ_LENGTH):
350
350
351 PrettyPrinter.__init__(self, output, max_width, newline, max_seq_length=max_seq_length)
351 PrettyPrinter.__init__(self, output, max_width, newline, max_seq_length=max_seq_length)
352 self.verbose = verbose
352 self.verbose = verbose
353 self.stack = []
353 self.stack = []
354 if singleton_pprinters is None:
354 if singleton_pprinters is None:
355 singleton_pprinters = _singleton_pprinters.copy()
355 singleton_pprinters = _singleton_pprinters.copy()
356 self.singleton_pprinters = singleton_pprinters
356 self.singleton_pprinters = singleton_pprinters
357 if type_pprinters is None:
357 if type_pprinters is None:
358 type_pprinters = _type_pprinters.copy()
358 type_pprinters = _type_pprinters.copy()
359 self.type_pprinters = type_pprinters
359 self.type_pprinters = type_pprinters
360 if deferred_pprinters is None:
360 if deferred_pprinters is None:
361 deferred_pprinters = _deferred_type_pprinters.copy()
361 deferred_pprinters = _deferred_type_pprinters.copy()
362 self.deferred_pprinters = deferred_pprinters
362 self.deferred_pprinters = deferred_pprinters
363
363
364 def pretty(self, obj):
364 def pretty(self, obj):
365 """Pretty print the given object."""
365 """Pretty print the given object."""
366 obj_id = id(obj)
366 obj_id = id(obj)
367 cycle = obj_id in self.stack
367 cycle = obj_id in self.stack
368 self.stack.append(obj_id)
368 self.stack.append(obj_id)
369 self.begin_group()
369 self.begin_group()
370 try:
370 try:
371 obj_class = _safe_getattr(obj, '__class__', None) or type(obj)
371 obj_class = _safe_getattr(obj, '__class__', None) or type(obj)
372 # First try to find registered singleton printers for the type.
372 # First try to find registered singleton printers for the type.
373 try:
373 try:
374 printer = self.singleton_pprinters[obj_id]
374 printer = self.singleton_pprinters[obj_id]
375 except (TypeError, KeyError):
375 except (TypeError, KeyError):
376 pass
376 pass
377 else:
377 else:
378 return printer(obj, self, cycle)
378 return printer(obj, self, cycle)
379 # Next walk the mro and check for either:
379 # Next walk the mro and check for either:
380 # 1) a registered printer
380 # 1) a registered printer
381 # 2) a _repr_pretty_ method
381 # 2) a _repr_pretty_ method
382 for cls in _get_mro(obj_class):
382 for cls in _get_mro(obj_class):
383 if cls in self.type_pprinters:
383 if cls in self.type_pprinters:
384 # printer registered in self.type_pprinters
384 # printer registered in self.type_pprinters
385 return self.type_pprinters[cls](obj, self, cycle)
385 return self.type_pprinters[cls](obj, self, cycle)
386 else:
386 else:
387 # deferred printer
387 # deferred printer
388 printer = self._in_deferred_types(cls)
388 printer = self._in_deferred_types(cls)
389 if printer is not None:
389 if printer is not None:
390 return printer(obj, self, cycle)
390 return printer(obj, self, cycle)
391 else:
391 else:
392 # Finally look for special method names.
392 # Finally look for special method names.
393 # Some objects automatically create any requested
393 # Some objects automatically create any requested
394 # attribute. Try to ignore most of them by checking for
394 # attribute. Try to ignore most of them by checking for
395 # callability.
395 # callability.
396 if '_repr_pretty_' in cls.__dict__:
396 if '_repr_pretty_' in cls.__dict__:
397 meth = cls._repr_pretty_
397 meth = cls._repr_pretty_
398 if callable(meth):
398 if callable(meth):
399 return meth(obj, self, cycle)
399 return meth(obj, self, cycle)
400 if cls is not object \
400 if cls is not object \
401 and callable(cls.__dict__.get('__repr__')):
401 and callable(cls.__dict__.get('__repr__')):
402 return _repr_pprint(obj, self, cycle)
402 return _repr_pprint(obj, self, cycle)
403
403
404 return _default_pprint(obj, self, cycle)
404 return _default_pprint(obj, self, cycle)
405 finally:
405 finally:
406 self.end_group()
406 self.end_group()
407 self.stack.pop()
407 self.stack.pop()
408
408
409 def _in_deferred_types(self, cls):
409 def _in_deferred_types(self, cls):
410 """
410 """
411 Check if the given class is specified in the deferred type registry.
411 Check if the given class is specified in the deferred type registry.
412
412
413 Returns the printer from the registry if it exists, and None if the
413 Returns the printer from the registry if it exists, and None if the
414 class is not in the registry. Successful matches will be moved to the
414 class is not in the registry. Successful matches will be moved to the
415 regular type registry for future use.
415 regular type registry for future use.
416 """
416 """
417 mod = _safe_getattr(cls, '__module__', None)
417 mod = _safe_getattr(cls, '__module__', None)
418 name = _safe_getattr(cls, '__name__', None)
418 name = _safe_getattr(cls, '__name__', None)
419 key = (mod, name)
419 key = (mod, name)
420 printer = None
420 printer = None
421 if key in self.deferred_pprinters:
421 if key in self.deferred_pprinters:
422 # Move the printer over to the regular registry.
422 # Move the printer over to the regular registry.
423 printer = self.deferred_pprinters.pop(key)
423 printer = self.deferred_pprinters.pop(key)
424 self.type_pprinters[cls] = printer
424 self.type_pprinters[cls] = printer
425 return printer
425 return printer
426
426
427
427
428 class Printable(object):
428 class Printable(object):
429
429
430 def output(self, stream, output_width):
430 def output(self, stream, output_width):
431 return output_width
431 return output_width
432
432
433
433
434 class Text(Printable):
434 class Text(Printable):
435
435
436 def __init__(self):
436 def __init__(self):
437 self.objs = []
437 self.objs = []
438 self.width = 0
438 self.width = 0
439
439
440 def output(self, stream, output_width):
440 def output(self, stream, output_width):
441 for obj in self.objs:
441 for obj in self.objs:
442 stream.write(obj)
442 stream.write(obj)
443 return output_width + self.width
443 return output_width + self.width
444
444
445 def add(self, obj, width):
445 def add(self, obj, width):
446 self.objs.append(obj)
446 self.objs.append(obj)
447 self.width += width
447 self.width += width
448
448
449
449
450 class Breakable(Printable):
450 class Breakable(Printable):
451
451
452 def __init__(self, seq, width, pretty):
452 def __init__(self, seq, width, pretty):
453 self.obj = seq
453 self.obj = seq
454 self.width = width
454 self.width = width
455 self.pretty = pretty
455 self.pretty = pretty
456 self.indentation = pretty.indentation
456 self.indentation = pretty.indentation
457 self.group = pretty.group_stack[-1]
457 self.group = pretty.group_stack[-1]
458 self.group.breakables.append(self)
458 self.group.breakables.append(self)
459
459
460 def output(self, stream, output_width):
460 def output(self, stream, output_width):
461 self.group.breakables.popleft()
461 self.group.breakables.popleft()
462 if self.group.want_break:
462 if self.group.want_break:
463 stream.write(self.pretty.newline)
463 stream.write(self.pretty.newline)
464 stream.write(' ' * self.indentation)
464 stream.write(' ' * self.indentation)
465 return self.indentation
465 return self.indentation
466 if not self.group.breakables:
466 if not self.group.breakables:
467 self.pretty.group_queue.remove(self.group)
467 self.pretty.group_queue.remove(self.group)
468 stream.write(self.obj)
468 stream.write(self.obj)
469 return output_width + self.width
469 return output_width + self.width
470
470
471
471
472 class Group(Printable):
472 class Group(Printable):
473
473
474 def __init__(self, depth):
474 def __init__(self, depth):
475 self.depth = depth
475 self.depth = depth
476 self.breakables = deque()
476 self.breakables = deque()
477 self.want_break = False
477 self.want_break = False
478
478
479
479
480 class GroupQueue(object):
480 class GroupQueue(object):
481
481
482 def __init__(self, *groups):
482 def __init__(self, *groups):
483 self.queue = []
483 self.queue = []
484 for group in groups:
484 for group in groups:
485 self.enq(group)
485 self.enq(group)
486
486
487 def enq(self, group):
487 def enq(self, group):
488 depth = group.depth
488 depth = group.depth
489 while depth > len(self.queue) - 1:
489 while depth > len(self.queue) - 1:
490 self.queue.append([])
490 self.queue.append([])
491 self.queue[depth].append(group)
491 self.queue[depth].append(group)
492
492
493 def deq(self):
493 def deq(self):
494 for stack in self.queue:
494 for stack in self.queue:
495 for idx, group in enumerate(reversed(stack)):
495 for idx, group in enumerate(reversed(stack)):
496 if group.breakables:
496 if group.breakables:
497 del stack[idx]
497 del stack[idx]
498 group.want_break = True
498 group.want_break = True
499 return group
499 return group
500 for group in stack:
500 for group in stack:
501 group.want_break = True
501 group.want_break = True
502 del stack[:]
502 del stack[:]
503
503
504 def remove(self, group):
504 def remove(self, group):
505 try:
505 try:
506 self.queue[group.depth].remove(group)
506 self.queue[group.depth].remove(group)
507 except ValueError:
507 except ValueError:
508 pass
508 pass
509
509
510
510
511 def _default_pprint(obj, p, cycle):
511 def _default_pprint(obj, p, cycle):
512 """
512 """
513 The default print function. Used if an object does not provide one and
513 The default print function. Used if an object does not provide one and
514 it's none of the builtin objects.
514 it's none of the builtin objects.
515 """
515 """
516 klass = _safe_getattr(obj, '__class__', None) or type(obj)
516 klass = _safe_getattr(obj, '__class__', None) or type(obj)
517 if _safe_getattr(klass, '__repr__', None) is not object.__repr__:
517 if _safe_getattr(klass, '__repr__', None) is not object.__repr__:
518 # A user-provided repr. Find newlines and replace them with p.break_()
518 # A user-provided repr. Find newlines and replace them with p.break_()
519 _repr_pprint(obj, p, cycle)
519 _repr_pprint(obj, p, cycle)
520 return
520 return
521 p.begin_group(1, '<')
521 p.begin_group(1, '<')
522 p.pretty(klass)
522 p.pretty(klass)
523 p.text(' at 0x%x' % id(obj))
523 p.text(' at 0x%x' % id(obj))
524 if cycle:
524 if cycle:
525 p.text(' ...')
525 p.text(' ...')
526 elif p.verbose:
526 elif p.verbose:
527 first = True
527 first = True
528 for key in dir(obj):
528 for key in dir(obj):
529 if not key.startswith('_'):
529 if not key.startswith('_'):
530 try:
530 try:
531 value = getattr(obj, key)
531 value = getattr(obj, key)
532 except AttributeError:
532 except AttributeError:
533 continue
533 continue
534 if isinstance(value, types.MethodType):
534 if isinstance(value, types.MethodType):
535 continue
535 continue
536 if not first:
536 if not first:
537 p.text(',')
537 p.text(',')
538 p.breakable()
538 p.breakable()
539 p.text(key)
539 p.text(key)
540 p.text('=')
540 p.text('=')
541 step = len(key) + 1
541 step = len(key) + 1
542 p.indentation += step
542 p.indentation += step
543 p.pretty(value)
543 p.pretty(value)
544 p.indentation -= step
544 p.indentation -= step
545 first = False
545 first = False
546 p.end_group(1, '>')
546 p.end_group(1, '>')
547
547
548
548
549 def _seq_pprinter_factory(start, end):
549 def _seq_pprinter_factory(start, end):
550 """
550 """
551 Factory that returns a pprint function useful for sequences. Used by
551 Factory that returns a pprint function useful for sequences. Used by
552 the default pprint for tuples, dicts, and lists.
552 the default pprint for tuples, dicts, and lists.
553 """
553 """
554 def inner(obj, p, cycle):
554 def inner(obj, p, cycle):
555 if cycle:
555 if cycle:
556 return p.text(start + '...' + end)
556 return p.text(start + '...' + end)
557 step = len(start)
557 step = len(start)
558 p.begin_group(step, start)
558 p.begin_group(step, start)
559 for idx, x in p._enumerate(obj):
559 for idx, x in p._enumerate(obj):
560 if idx:
560 if idx:
561 p.text(',')
561 p.text(',')
562 p.breakable()
562 p.breakable()
563 p.pretty(x)
563 p.pretty(x)
564 if len(obj) == 1 and type(obj) is tuple:
564 if len(obj) == 1 and type(obj) is tuple:
565 # Special case for 1-item tuples.
565 # Special case for 1-item tuples.
566 p.text(',')
566 p.text(',')
567 p.end_group(step, end)
567 p.end_group(step, end)
568 return inner
568 return inner
569
569
570
570
571 def _set_pprinter_factory(start, end):
571 def _set_pprinter_factory(start, end):
572 """
572 """
573 Factory that returns a pprint function useful for sets and frozensets.
573 Factory that returns a pprint function useful for sets and frozensets.
574 """
574 """
575 def inner(obj, p, cycle):
575 def inner(obj, p, cycle):
576 if cycle:
576 if cycle:
577 return p.text(start + '...' + end)
577 return p.text(start + '...' + end)
578 if len(obj) == 0:
578 if len(obj) == 0:
579 # Special case.
579 # Special case.
580 p.text(type(obj).__name__ + '()')
580 p.text(type(obj).__name__ + '()')
581 else:
581 else:
582 step = len(start)
582 step = len(start)
583 p.begin_group(step, start)
583 p.begin_group(step, start)
584 # Like dictionary keys, we will try to sort the items if there aren't too many
584 # Like dictionary keys, we will try to sort the items if there aren't too many
585 if not (p.max_seq_length and len(obj) >= p.max_seq_length):
585 if not (p.max_seq_length and len(obj) >= p.max_seq_length):
586 items = _sorted_for_pprint(obj)
586 items = _sorted_for_pprint(obj)
587 else:
587 else:
588 items = obj
588 items = obj
589 for idx, x in p._enumerate(items):
589 for idx, x in p._enumerate(items):
590 if idx:
590 if idx:
591 p.text(',')
591 p.text(',')
592 p.breakable()
592 p.breakable()
593 p.pretty(x)
593 p.pretty(x)
594 p.end_group(step, end)
594 p.end_group(step, end)
595 return inner
595 return inner
596
596
597
597
598 def _dict_pprinter_factory(start, end):
598 def _dict_pprinter_factory(start, end):
599 """
599 """
600 Factory that returns a pprint function used by the default pprint of
600 Factory that returns a pprint function used by the default pprint of
601 dicts and dict proxies.
601 dicts and dict proxies.
602 """
602 """
603 def inner(obj, p, cycle):
603 def inner(obj, p, cycle):
604 if cycle:
604 if cycle:
605 return p.text('{...}')
605 return p.text('{...}')
606 step = len(start)
606 step = len(start)
607 p.begin_group(step, start)
607 p.begin_group(step, start)
608 keys = obj.keys()
608 keys = obj.keys()
609 # if dict isn't large enough to be truncated, sort keys before displaying
609 # if dict isn't large enough to be truncated, sort keys before displaying
610 # From Python 3.7, dicts preserve order by definition, so we don't sort.
610 # From Python 3.7, dicts preserve order by definition, so we don't sort.
611 if not DICT_IS_ORDERED \
611 if not DICT_IS_ORDERED \
612 and not (p.max_seq_length and len(obj) >= p.max_seq_length):
612 and not (p.max_seq_length and len(obj) >= p.max_seq_length):
613 keys = _sorted_for_pprint(keys)
613 keys = _sorted_for_pprint(keys)
614 for idx, key in p._enumerate(keys):
614 for idx, key in p._enumerate(keys):
615 if idx:
615 if idx:
616 p.text(',')
616 p.text(',')
617 p.breakable()
617 p.breakable()
618 p.pretty(key)
618 p.pretty(key)
619 p.text(': ')
619 p.text(': ')
620 p.pretty(obj[key])
620 p.pretty(obj[key])
621 p.end_group(step, end)
621 p.end_group(step, end)
622 return inner
622 return inner
623
623
624
624
625 def _super_pprint(obj, p, cycle):
625 def _super_pprint(obj, p, cycle):
626 """The pprint for the super type."""
626 """The pprint for the super type."""
627 p.begin_group(8, '<super: ')
627 p.begin_group(8, '<super: ')
628 p.pretty(obj.__thisclass__)
628 p.pretty(obj.__thisclass__)
629 p.text(',')
629 p.text(',')
630 p.breakable()
630 p.breakable()
631 if PYPY: # In PyPy, super() objects don't have __self__ attributes
631 if PYPY: # In PyPy, super() objects don't have __self__ attributes
632 dself = obj.__repr__.__self__
632 dself = obj.__repr__.__self__
633 p.pretty(None if dself is obj else dself)
633 p.pretty(None if dself is obj else dself)
634 else:
634 else:
635 p.pretty(obj.__self__)
635 p.pretty(obj.__self__)
636 p.end_group(8, '>')
636 p.end_group(8, '>')
637
637
638
638
639 def _re_pattern_pprint(obj, p, cycle):
639 def _re_pattern_pprint(obj, p, cycle):
640 """The pprint function for regular expression patterns."""
640 """The pprint function for regular expression patterns."""
641 p.text('re.compile(')
641 p.text('re.compile(')
642 pattern = repr(obj.pattern)
642 pattern = repr(obj.pattern)
643 if pattern[:1] in 'uU':
643 if pattern[:1] in 'uU':
644 pattern = pattern[1:]
644 pattern = pattern[1:]
645 prefix = 'ur'
645 prefix = 'ur'
646 else:
646 else:
647 prefix = 'r'
647 prefix = 'r'
648 pattern = prefix + pattern.replace('\\\\', '\\')
648 pattern = prefix + pattern.replace('\\\\', '\\')
649 p.text(pattern)
649 p.text(pattern)
650 if obj.flags:
650 if obj.flags:
651 p.text(',')
651 p.text(',')
652 p.breakable()
652 p.breakable()
653 done_one = False
653 done_one = False
654 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
654 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
655 'UNICODE', 'VERBOSE', 'DEBUG'):
655 'UNICODE', 'VERBOSE', 'DEBUG'):
656 if obj.flags & getattr(re, flag):
656 if obj.flags & getattr(re, flag):
657 if done_one:
657 if done_one:
658 p.text('|')
658 p.text('|')
659 p.text('re.' + flag)
659 p.text('re.' + flag)
660 done_one = True
660 done_one = True
661 p.text(')')
661 p.text(')')
662
662
663
663
664 def _type_pprint(obj, p, cycle):
664 def _type_pprint(obj, p, cycle):
665 """The pprint for classes and types."""
665 """The pprint for classes and types."""
666 # Heap allocated types might not have the module attribute,
666 # Heap allocated types might not have the module attribute,
667 # and others may set it to None.
667 # and others may set it to None.
668
668
669 # Checks for a __repr__ override in the metaclass. Can't compare the
669 # Checks for a __repr__ override in the metaclass. Can't compare the
670 # type(obj).__repr__ directly because in PyPy the representation function
670 # type(obj).__repr__ directly because in PyPy the representation function
671 # inherited from type isn't the same type.__repr__
671 # inherited from type isn't the same type.__repr__
672 if [m for m in _get_mro(type(obj)) if "__repr__" in vars(m)][:1] != [type]:
672 if [m for m in _get_mro(type(obj)) if "__repr__" in vars(m)][:1] != [type]:
673 _repr_pprint(obj, p, cycle)
673 _repr_pprint(obj, p, cycle)
674 return
674 return
675
675
676 mod = _safe_getattr(obj, '__module__', None)
676 mod = _safe_getattr(obj, '__module__', None)
677 try:
677 try:
678 name = obj.__qualname__
678 name = obj.__qualname__
679 if not isinstance(name, str):
679 if not isinstance(name, str):
680 # This can happen if the type implements __qualname__ as a property
680 # This can happen if the type implements __qualname__ as a property
681 # or other descriptor in Python 2.
681 # or other descriptor in Python 2.
682 raise Exception("Try __name__")
682 raise Exception("Try __name__")
683 except Exception:
683 except Exception:
684 name = obj.__name__
684 name = obj.__name__
685 if not isinstance(name, str):
685 if not isinstance(name, str):
686 name = '<unknown type>'
686 name = '<unknown type>'
687
687
688 if mod in (None, '__builtin__', 'builtins', 'exceptions'):
688 if mod in (None, '__builtin__', 'builtins', 'exceptions'):
689 p.text(name)
689 p.text(name)
690 else:
690 else:
691 p.text(mod + '.' + name)
691 p.text(mod + '.' + name)
692
692
693
693
694 def _repr_pprint(obj, p, cycle):
694 def _repr_pprint(obj, p, cycle):
695 """A pprint that just redirects to the normal repr function."""
695 """A pprint that just redirects to the normal repr function."""
696 # Find newlines and replace them with p.break_()
696 # Find newlines and replace them with p.break_()
697 output = repr(obj)
697 output = repr(obj)
698 for idx,output_line in enumerate(output.splitlines()):
698 for idx,output_line in enumerate(output.splitlines()):
699 if idx:
699 if idx:
700 p.break_()
700 p.break_()
701 p.text(output_line)
701 p.text(output_line)
702
702
703
703
704 def _function_pprint(obj, p, cycle):
704 def _function_pprint(obj, p, cycle):
705 """Base pprint for all functions and builtin functions."""
705 """Base pprint for all functions and builtin functions."""
706 name = _safe_getattr(obj, '__qualname__', obj.__name__)
706 name = _safe_getattr(obj, '__qualname__', obj.__name__)
707 mod = obj.__module__
707 mod = obj.__module__
708 if mod and mod not in ('__builtin__', 'builtins', 'exceptions'):
708 if mod and mod not in ('__builtin__', 'builtins', 'exceptions'):
709 name = mod + '.' + name
709 name = mod + '.' + name
710 try:
710 try:
711 func_def = name + str(signature(obj))
711 func_def = name + str(signature(obj))
712 except ValueError:
712 except ValueError:
713 func_def = name
713 func_def = name
714 p.text('<function %s>' % func_def)
714 p.text('<function %s>' % func_def)
715
715
716
716
717 def _exception_pprint(obj, p, cycle):
717 def _exception_pprint(obj, p, cycle):
718 """Base pprint for all exceptions."""
718 """Base pprint for all exceptions."""
719 name = getattr(obj.__class__, '__qualname__', obj.__class__.__name__)
719 name = getattr(obj.__class__, '__qualname__', obj.__class__.__name__)
720 if obj.__class__.__module__ not in ('exceptions', 'builtins'):
720 if obj.__class__.__module__ not in ('exceptions', 'builtins'):
721 name = '%s.%s' % (obj.__class__.__module__, name)
721 name = '%s.%s' % (obj.__class__.__module__, name)
722 step = len(name) + 1
722 step = len(name) + 1
723 p.begin_group(step, name + '(')
723 p.begin_group(step, name + '(')
724 for idx, arg in enumerate(getattr(obj, 'args', ())):
724 for idx, arg in enumerate(getattr(obj, 'args', ())):
725 if idx:
725 if idx:
726 p.text(',')
726 p.text(',')
727 p.breakable()
727 p.breakable()
728 p.pretty(arg)
728 p.pretty(arg)
729 p.end_group(step, ')')
729 p.end_group(step, ')')
730
730
731
731
732 #: the exception base
732 #: the exception base
733 try:
733 try:
734 _exception_base = BaseException
734 _exception_base = BaseException
735 except NameError:
735 except NameError:
736 _exception_base = Exception
736 _exception_base = Exception
737
737
738
738
739 #: printers for builtin types
739 #: printers for builtin types
740 _type_pprinters = {
740 _type_pprinters = {
741 int: _repr_pprint,
741 int: _repr_pprint,
742 float: _repr_pprint,
742 float: _repr_pprint,
743 str: _repr_pprint,
743 str: _repr_pprint,
744 tuple: _seq_pprinter_factory('(', ')'),
744 tuple: _seq_pprinter_factory('(', ')'),
745 list: _seq_pprinter_factory('[', ']'),
745 list: _seq_pprinter_factory('[', ']'),
746 dict: _dict_pprinter_factory('{', '}'),
746 dict: _dict_pprinter_factory('{', '}'),
747 set: _set_pprinter_factory('{', '}'),
747 set: _set_pprinter_factory('{', '}'),
748 frozenset: _set_pprinter_factory('frozenset({', '})'),
748 frozenset: _set_pprinter_factory('frozenset({', '})'),
749 super: _super_pprint,
749 super: _super_pprint,
750 _re_pattern_type: _re_pattern_pprint,
750 _re_pattern_type: _re_pattern_pprint,
751 type: _type_pprint,
751 type: _type_pprint,
752 types.FunctionType: _function_pprint,
752 types.FunctionType: _function_pprint,
753 types.BuiltinFunctionType: _function_pprint,
753 types.BuiltinFunctionType: _function_pprint,
754 types.MethodType: _repr_pprint,
754 types.MethodType: _repr_pprint,
755 datetime.datetime: _repr_pprint,
755 datetime.datetime: _repr_pprint,
756 datetime.timedelta: _repr_pprint,
756 datetime.timedelta: _repr_pprint,
757 _exception_base: _exception_pprint
757 _exception_base: _exception_pprint
758 }
758 }
759
759
760 # render os.environ like a dict
760 # render os.environ like a dict
761 _env_type = type(os.environ)
761 _env_type = type(os.environ)
762 # future-proof in case os.environ becomes a plain dict?
762 # future-proof in case os.environ becomes a plain dict?
763 if _env_type is not dict:
763 if _env_type is not dict:
764 _type_pprinters[_env_type] = _dict_pprinter_factory('environ{', '}')
764 _type_pprinters[_env_type] = _dict_pprinter_factory('environ{', '}')
765
765
766 try:
766 try:
767 # In PyPy, types.DictProxyType is dict, setting the dictproxy printer
767 # In PyPy, types.DictProxyType is dict, setting the dictproxy printer
768 # using dict.setdefault avoids overwritting the dict printer
768 # using dict.setdefault avoids overwriting the dict printer
769 _type_pprinters.setdefault(types.DictProxyType,
769 _type_pprinters.setdefault(types.DictProxyType,
770 _dict_pprinter_factory('dict_proxy({', '})'))
770 _dict_pprinter_factory('dict_proxy({', '})'))
771 _type_pprinters[types.ClassType] = _type_pprint
771 _type_pprinters[types.ClassType] = _type_pprint
772 _type_pprinters[types.SliceType] = _repr_pprint
772 _type_pprinters[types.SliceType] = _repr_pprint
773 except AttributeError: # Python 3
773 except AttributeError: # Python 3
774 _type_pprinters[types.MappingProxyType] = \
774 _type_pprinters[types.MappingProxyType] = \
775 _dict_pprinter_factory('mappingproxy({', '})')
775 _dict_pprinter_factory('mappingproxy({', '})')
776 _type_pprinters[slice] = _repr_pprint
776 _type_pprinters[slice] = _repr_pprint
777
777
778 try:
778 try:
779 _type_pprinters[long] = _repr_pprint
779 _type_pprinters[long] = _repr_pprint
780 _type_pprinters[unicode] = _repr_pprint
780 _type_pprinters[unicode] = _repr_pprint
781 except NameError:
781 except NameError:
782 _type_pprinters[range] = _repr_pprint
782 _type_pprinters[range] = _repr_pprint
783 _type_pprinters[bytes] = _repr_pprint
783 _type_pprinters[bytes] = _repr_pprint
784
784
785 #: printers for types specified by name
785 #: printers for types specified by name
786 _deferred_type_pprinters = {
786 _deferred_type_pprinters = {
787 }
787 }
788
788
789 def for_type(typ, func):
789 def for_type(typ, func):
790 """
790 """
791 Add a pretty printer for a given type.
791 Add a pretty printer for a given type.
792 """
792 """
793 oldfunc = _type_pprinters.get(typ, None)
793 oldfunc = _type_pprinters.get(typ, None)
794 if func is not None:
794 if func is not None:
795 # To support easy restoration of old pprinters, we need to ignore Nones.
795 # To support easy restoration of old pprinters, we need to ignore Nones.
796 _type_pprinters[typ] = func
796 _type_pprinters[typ] = func
797 return oldfunc
797 return oldfunc
798
798
799 def for_type_by_name(type_module, type_name, func):
799 def for_type_by_name(type_module, type_name, func):
800 """
800 """
801 Add a pretty printer for a type specified by the module and name of a type
801 Add a pretty printer for a type specified by the module and name of a type
802 rather than the type object itself.
802 rather than the type object itself.
803 """
803 """
804 key = (type_module, type_name)
804 key = (type_module, type_name)
805 oldfunc = _deferred_type_pprinters.get(key, None)
805 oldfunc = _deferred_type_pprinters.get(key, None)
806 if func is not None:
806 if func is not None:
807 # To support easy restoration of old pprinters, we need to ignore Nones.
807 # To support easy restoration of old pprinters, we need to ignore Nones.
808 _deferred_type_pprinters[key] = func
808 _deferred_type_pprinters[key] = func
809 return oldfunc
809 return oldfunc
810
810
811
811
812 #: printers for the default singletons
812 #: printers for the default singletons
813 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
813 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
814 NotImplemented]), _repr_pprint)
814 NotImplemented]), _repr_pprint)
815
815
816
816
817 def _defaultdict_pprint(obj, p, cycle):
817 def _defaultdict_pprint(obj, p, cycle):
818 name = obj.__class__.__name__
818 name = obj.__class__.__name__
819 with p.group(len(name) + 1, name + '(', ')'):
819 with p.group(len(name) + 1, name + '(', ')'):
820 if cycle:
820 if cycle:
821 p.text('...')
821 p.text('...')
822 else:
822 else:
823 p.pretty(obj.default_factory)
823 p.pretty(obj.default_factory)
824 p.text(',')
824 p.text(',')
825 p.breakable()
825 p.breakable()
826 p.pretty(dict(obj))
826 p.pretty(dict(obj))
827
827
828 def _ordereddict_pprint(obj, p, cycle):
828 def _ordereddict_pprint(obj, p, cycle):
829 name = obj.__class__.__name__
829 name = obj.__class__.__name__
830 with p.group(len(name) + 1, name + '(', ')'):
830 with p.group(len(name) + 1, name + '(', ')'):
831 if cycle:
831 if cycle:
832 p.text('...')
832 p.text('...')
833 elif len(obj):
833 elif len(obj):
834 p.pretty(list(obj.items()))
834 p.pretty(list(obj.items()))
835
835
836 def _deque_pprint(obj, p, cycle):
836 def _deque_pprint(obj, p, cycle):
837 name = obj.__class__.__name__
837 name = obj.__class__.__name__
838 with p.group(len(name) + 1, name + '(', ')'):
838 with p.group(len(name) + 1, name + '(', ')'):
839 if cycle:
839 if cycle:
840 p.text('...')
840 p.text('...')
841 else:
841 else:
842 p.pretty(list(obj))
842 p.pretty(list(obj))
843
843
844
844
845 def _counter_pprint(obj, p, cycle):
845 def _counter_pprint(obj, p, cycle):
846 name = obj.__class__.__name__
846 name = obj.__class__.__name__
847 with p.group(len(name) + 1, name + '(', ')'):
847 with p.group(len(name) + 1, name + '(', ')'):
848 if cycle:
848 if cycle:
849 p.text('...')
849 p.text('...')
850 elif len(obj):
850 elif len(obj):
851 p.pretty(dict(obj))
851 p.pretty(dict(obj))
852
852
853 for_type_by_name('collections', 'defaultdict', _defaultdict_pprint)
853 for_type_by_name('collections', 'defaultdict', _defaultdict_pprint)
854 for_type_by_name('collections', 'OrderedDict', _ordereddict_pprint)
854 for_type_by_name('collections', 'OrderedDict', _ordereddict_pprint)
855 for_type_by_name('collections', 'deque', _deque_pprint)
855 for_type_by_name('collections', 'deque', _deque_pprint)
856 for_type_by_name('collections', 'Counter', _counter_pprint)
856 for_type_by_name('collections', 'Counter', _counter_pprint)
857
857
858 if __name__ == '__main__':
858 if __name__ == '__main__':
859 from random import randrange
859 from random import randrange
860 class Foo(object):
860 class Foo(object):
861 def __init__(self):
861 def __init__(self):
862 self.foo = 1
862 self.foo = 1
863 self.bar = re.compile(r'\s+')
863 self.bar = re.compile(r'\s+')
864 self.blub = dict.fromkeys(range(30), randrange(1, 40))
864 self.blub = dict.fromkeys(range(30), randrange(1, 40))
865 self.hehe = 23424.234234
865 self.hehe = 23424.234234
866 self.list = ["blub", "blah", self]
866 self.list = ["blub", "blah", self]
867
867
868 def get_foo(self):
868 def get_foo(self):
869 print("foo")
869 print("foo")
870
870
871 pprint(Foo(), verbose=True)
871 pprint(Foo(), verbose=True)
@@ -1,46 +1,46 b''
1 """Some simple tests for the plugin while running scripts.
1 """Some simple tests for the plugin while running scripts.
2 """
2 """
3 # Module imports
3 # Module imports
4 # Std lib
4 # Std lib
5 import inspect
5 import inspect
6
6
7 # Our own
7 # Our own
8
8
9 #-----------------------------------------------------------------------------
9 #-----------------------------------------------------------------------------
10 # Testing functions
10 # Testing functions
11
11
12 def test_trivial():
12 def test_trivial():
13 """A trivial passing test."""
13 """A trivial passing test."""
14 pass
14 pass
15
15
16 def doctest_run():
16 def doctest_run():
17 """Test running a trivial script.
17 """Test running a trivial script.
18
18
19 In [13]: run simplevars.py
19 In [13]: run simplevars.py
20 x is: 1
20 x is: 1
21 """
21 """
22
22
23 def doctest_runvars():
23 def doctest_runvars():
24 """Test that variables defined in scripts get loaded correcly via %run.
24 """Test that variables defined in scripts get loaded correclty via %run.
25
25
26 In [13]: run simplevars.py
26 In [13]: run simplevars.py
27 x is: 1
27 x is: 1
28
28
29 In [14]: x
29 In [14]: x
30 Out[14]: 1
30 Out[14]: 1
31 """
31 """
32
32
33 def doctest_ivars():
33 def doctest_ivars():
34 """Test that variables defined interactively are picked up.
34 """Test that variables defined interactively are picked up.
35 In [5]: zz=1
35 In [5]: zz=1
36
36
37 In [6]: zz
37 In [6]: zz
38 Out[6]: 1
38 Out[6]: 1
39 """
39 """
40
40
41 def doctest_refs():
41 def doctest_refs():
42 """DocTest reference holding issues when running scripts.
42 """DocTest reference holding issues when running scripts.
43
43
44 In [32]: run show_refs.py
44 In [32]: run show_refs.py
45 c referrers: [<... 'dict'>]
45 c referrers: [<... 'dict'>]
46 """
46 """
@@ -1,96 +1,95 b''
1 # encoding: utf-8
1 # encoding: utf-8
2 """
2 """
3 Utilities for working with stack frames.
3 Utilities for working with stack frames.
4 """
4 """
5
5
6 #-----------------------------------------------------------------------------
6 #-----------------------------------------------------------------------------
7 # Copyright (C) 2008-2011 The IPython Development Team
7 # Copyright (C) 2008-2011 The IPython Development Team
8 #
8 #
9 # Distributed under the terms of the BSD License. The full license is in
9 # Distributed under the terms of the BSD License. The full license is in
10 # the file COPYING, distributed as part of this software.
10 # the file COPYING, distributed as part of this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16
16
17 import sys
17 import sys
18 from IPython.utils import py3compat
18 from IPython.utils import py3compat
19
19
20 #-----------------------------------------------------------------------------
20 #-----------------------------------------------------------------------------
21 # Code
21 # Code
22 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
23
23
24 def extract_vars(*names,**kw):
24 def extract_vars(*names,**kw):
25 """Extract a set of variables by name from another frame.
25 """Extract a set of variables by name from another frame.
26
26
27 Parameters
27 Parameters
28 ----------
28 ----------
29 *names : str
29 *names : str
30 One or more variable names which will be extracted from the caller's
30 One or more variable names which will be extracted from the caller's
31 frame.
31 frame.
32
32
33 depth : integer, optional
33 depth : integer, optional
34 How many frames in the stack to walk when looking for your variables.
34 How many frames in the stack to walk when looking for your variables.
35 The default is 0, which will use the frame where the call was made.
35 The default is 0, which will use the frame where the call was made.
36
36
37
37
38 Examples
38 Examples
39 --------
39 --------
40 ::
40 ::
41
41
42 In [2]: def func(x):
42 In [2]: def func(x):
43 ...: y = 1
43 ...: y = 1
44 ...: print(sorted(extract_vars('x','y').items()))
44 ...: print(sorted(extract_vars('x','y').items()))
45 ...:
45 ...:
46
46
47 In [3]: func('hello')
47 In [3]: func('hello')
48 [('x', 'hello'), ('y', 1)]
48 [('x', 'hello'), ('y', 1)]
49 """
49 """
50
50
51 depth = kw.get('depth',0)
51 depth = kw.get('depth',0)
52
52
53 callerNS = sys._getframe(depth+1).f_locals
53 callerNS = sys._getframe(depth+1).f_locals
54 return dict((k,callerNS[k]) for k in names)
54 return dict((k,callerNS[k]) for k in names)
55
55
56
56
57 def extract_vars_above(*names):
57 def extract_vars_above(*names):
58 """Extract a set of variables by name from another frame.
58 """Extract a set of variables by name from another frame.
59
59
60 Similar to extractVars(), but with a specified depth of 1, so that names
60 Similar to extractVars(), but with a specified depth of 1, so that names
61 are exctracted exactly from above the caller.
61 are extracted exactly from above the caller.
62
62
63 This is simply a convenience function so that the very common case (for us)
63 This is simply a convenience function so that the very common case (for us)
64 of skipping exactly 1 frame doesn't have to construct a special dict for
64 of skipping exactly 1 frame doesn't have to construct a special dict for
65 keyword passing."""
65 keyword passing."""
66
66
67 callerNS = sys._getframe(2).f_locals
67 callerNS = sys._getframe(2).f_locals
68 return dict((k,callerNS[k]) for k in names)
68 return dict((k,callerNS[k]) for k in names)
69
69
70
70
71 def debugx(expr,pre_msg=''):
71 def debugx(expr,pre_msg=''):
72 """Print the value of an expression from the caller's frame.
72 """Print the value of an expression from the caller's frame.
73
73
74 Takes an expression, evaluates it in the caller's frame and prints both
74 Takes an expression, evaluates it in the caller's frame and prints both
75 the given expression and the resulting value (as well as a debug mark
75 the given expression and the resulting value (as well as a debug mark
76 indicating the name of the calling function. The input must be of a form
76 indicating the name of the calling function. The input must be of a form
77 suitable for eval().
77 suitable for eval().
78
78
79 An optional message can be passed, which will be prepended to the printed
79 An optional message can be passed, which will be prepended to the printed
80 expr->value pair."""
80 expr->value pair."""
81
81
82 cf = sys._getframe(1)
82 cf = sys._getframe(1)
83 print('[DBG:%s] %s%s -> %r' % (cf.f_code.co_name,pre_msg,expr,
83 print('[DBG:%s] %s%s -> %r' % (cf.f_code.co_name,pre_msg,expr,
84 eval(expr,cf.f_globals,cf.f_locals)))
84 eval(expr,cf.f_globals,cf.f_locals)))
85
85
86
86
87 # deactivate it by uncommenting the following line, which makes it a no-op
87 # deactivate it by uncommenting the following line, which makes it a no-op
88 #def debugx(expr,pre_msg=''): pass
88 #def debugx(expr,pre_msg=''): pass
89
89
90 def extract_module_locals(depth=0):
90 def extract_module_locals(depth=0):
91 """Returns (module, locals) of the function `depth` frames away from the caller"""
91 """Returns (module, locals) of the function `depth` frames away from the caller"""
92 f = sys._getframe(depth + 1)
92 f = sys._getframe(depth + 1)
93 global_ns = f.f_globals
93 global_ns = f.f_globals
94 module = sys.modules[global_ns['__name__']]
94 module = sys.modules[global_ns['__name__']]
95 return (module, f.f_locals)
95 return (module, f.f_locals)
96
General Comments 0
You need to be logged in to leave comments. Login now