##// END OF EJS Templates
Misc. typo fixes ...
luz.paz -
Show More
@@ -1,161 +1,161 b''
1 1 """Compiler tools with improved interactive support.
2 2
3 3 Provides compilation machinery similar to codeop, but with caching support so
4 4 we can provide interactive tracebacks.
5 5
6 6 Authors
7 7 -------
8 8 * Robert Kern
9 9 * Fernando Perez
10 10 * Thomas Kluyver
11 11 """
12 12
13 13 # Note: though it might be more natural to name this module 'compiler', that
14 14 # name is in the stdlib and name collisions with the stdlib tend to produce
15 15 # weird problems (often with third-party tools).
16 16
17 17 #-----------------------------------------------------------------------------
18 18 # Copyright (C) 2010-2011 The IPython Development Team.
19 19 #
20 20 # Distributed under the terms of the BSD License.
21 21 #
22 22 # The full license is in the file COPYING.txt, distributed with this software.
23 23 #-----------------------------------------------------------------------------
24 24
25 25 #-----------------------------------------------------------------------------
26 26 # Imports
27 27 #-----------------------------------------------------------------------------
28 28
29 29 # Stdlib imports
30 30 import __future__
31 31 from ast import PyCF_ONLY_AST
32 32 import codeop
33 33 import functools
34 34 import hashlib
35 35 import linecache
36 36 import operator
37 37 import time
38 38
39 39 #-----------------------------------------------------------------------------
40 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 44 # this is used as a bitmask to extract future-related code flags.
45 45 PyCF_MASK = functools.reduce(operator.or_,
46 46 (getattr(__future__, fname).compiler_flag
47 47 for fname in __future__.all_feature_names))
48 48
49 49 #-----------------------------------------------------------------------------
50 50 # Local utilities
51 51 #-----------------------------------------------------------------------------
52 52
53 53 def code_name(code, number=0):
54 54 """ Compute a (probably) unique name for code for caching.
55 55
56 56 This now expects code to be unicode.
57 57 """
58 58 hash_digest = hashlib.sha1(code.encode("utf-8")).hexdigest()
59 59 # Include the number and 12 characters of the hash in the name. It's
60 60 # pretty much impossible that in a single session we'll have collisions
61 61 # even with truncated hashes, and the full one makes tracebacks too long
62 62 return '<ipython-input-{0}-{1}>'.format(number, hash_digest[:12])
63 63
64 64 #-----------------------------------------------------------------------------
65 65 # Classes and functions
66 66 #-----------------------------------------------------------------------------
67 67
68 68 class CachingCompiler(codeop.Compile):
69 69 """A compiler that caches code compiled from interactive statements.
70 70 """
71 71
72 72 def __init__(self):
73 73 codeop.Compile.__init__(self)
74 74
75 75 # This is ugly, but it must be done this way to allow multiple
76 76 # simultaneous ipython instances to coexist. Since Python itself
77 77 # directly accesses the data structures in the linecache module, and
78 78 # the cache therein is global, we must work with that data structure.
79 79 # We must hold a reference to the original checkcache routine and call
80 80 # that in our own check_cache() below, but the special IPython cache
81 81 # must also be shared by all IPython instances. If we were to hold
82 82 # separate caches (one in each CachingCompiler instance), any call made
83 83 # by Python itself to linecache.checkcache() would obliterate the
84 84 # cached data from the other IPython instances.
85 85 if not hasattr(linecache, '_ipython_cache'):
86 86 linecache._ipython_cache = {}
87 87 if not hasattr(linecache, '_checkcache_ori'):
88 88 linecache._checkcache_ori = linecache.checkcache
89 89 # Now, we must monkeypatch the linecache directly so that parts of the
90 90 # stdlib that call it outside our control go through our codepath
91 91 # (otherwise we'd lose our tracebacks).
92 92 linecache.checkcache = check_linecache_ipython
93 93
94 94
95 95 def _fix_module_ds(self, module):
96 96 """
97 97 Starting in python 3.7 the AST for mule have changed, and if
98 98 the first expressions encountered is a string it is attached to the
99 99 `docstring` attribute of the `Module` ast node.
100 100
101 101 This breaks IPython, as if this string is the only expression, IPython
102 102 will not return it as the result of the current cell.
103 103 """
104 104 from ast import Str, Expr, Module, fix_missing_locations
105 105 docstring = getattr(module, 'docstring', None)
106 106 if not docstring:
107 107 return module
108 108 new_body=[Expr(Str(docstring, lineno=1, col_offset=0), lineno=1, col_offset=0)]
109 109 new_body.extend(module.body)
110 110 return fix_missing_locations(Module(new_body))
111 111
112 112 def ast_parse(self, source, filename='<unknown>', symbol='exec'):
113 113 """Parse code to an AST with the current compiler flags active.
114 114
115 115 Arguments are exactly the same as ast.parse (in the standard library),
116 116 and are passed to the built-in compile function."""
117 117 return self._fix_module_ds(compile(source, filename, symbol, self.flags | PyCF_ONLY_AST, 1))
118 118
119 119 def reset_compiler_flags(self):
120 120 """Reset compiler flags to default state."""
121 121 # This value is copied from codeop.Compile.__init__, so if that ever
122 122 # changes, it will need to be updated.
123 123 self.flags = codeop.PyCF_DONT_IMPLY_DEDENT
124 124
125 125 @property
126 126 def compiler_flags(self):
127 127 """Flags currently active in the compilation process.
128 128 """
129 129 return self.flags
130 130
131 131 def cache(self, code, number=0):
132 132 """Make a name for a block of code, and cache the code.
133 133
134 134 Parameters
135 135 ----------
136 136 code : str
137 137 The Python source code to cache.
138 138 number : int
139 139 A number which forms part of the code's name. Used for the execution
140 140 counter.
141 141
142 142 Returns
143 143 -------
144 144 The name of the cached code (as a string). Pass this as the filename
145 145 argument to compilation, so that tracebacks are correctly hooked up.
146 146 """
147 147 name = code_name(code, number)
148 148 entry = (len(code), time.time(),
149 149 [line+'\n' for line in code.splitlines()], name)
150 150 linecache.cache[name] = entry
151 151 linecache._ipython_cache[name] = entry
152 152 return name
153 153
154 154 def check_linecache_ipython(*args):
155 155 """Call linecache.checkcache() safely protecting our cached values.
156 156 """
157 157 # First call the original checkcache as intended
158 158 linecache._checkcache_ori(*args)
159 159 # Then, update back the cache with our data, so that tracebacks related
160 160 # to our compiled codes can be produced.
161 161 linecache.cache.update(linecache._ipython_cache)
@@ -1,229 +1,229 b''
1 1 """Hooks for IPython.
2 2
3 3 In Python, it is possible to overwrite any method of any object if you really
4 4 want to. But IPython exposes a few 'hooks', methods which are *designed* to
5 5 be overwritten by users for customization purposes. This module defines the
6 6 default versions of all such hooks, which get used by IPython if not
7 7 overridden by the user.
8 8
9 9 Hooks are simple functions, but they should be declared with ``self`` as their
10 10 first argument, because when activated they are registered into IPython as
11 11 instance methods. The self argument will be the IPython running instance
12 12 itself, so hooks have full access to the entire IPython object.
13 13
14 14 If you wish to define a new hook and activate it, you can make an :doc:`extension
15 15 </config/extensions/index>` or a :ref:`startup script <startup_files>`. For
16 16 example, you could use a startup file like this::
17 17
18 18 import os
19 19
20 20 def calljed(self,filename, linenum):
21 21 "My editor hook calls the jed editor directly."
22 22 print "Calling my own editor, jed ..."
23 23 if os.system('jed +%d %s' % (linenum,filename)) != 0:
24 24 raise TryNext()
25 25
26 26 def load_ipython_extension(ip):
27 27 ip.set_hook('editor', calljed)
28 28
29 29 """
30 30
31 31 #*****************************************************************************
32 32 # Copyright (C) 2005 Fernando Perez. <fperez@colorado.edu>
33 33 #
34 34 # Distributed under the terms of the BSD License. The full license is in
35 35 # the file COPYING, distributed as part of this software.
36 36 #*****************************************************************************
37 37
38 38 import os
39 39 import subprocess
40 40 import warnings
41 41 import sys
42 42
43 43 from IPython.core.error import TryNext
44 44
45 45 # List here all the default hooks. For now it's just the editor functions
46 46 # but over time we'll move here all the public API for user-accessible things.
47 47
48 48 __all__ = ['editor', 'synchronize_with_editor',
49 49 'shutdown_hook', 'late_startup_hook',
50 50 'show_in_pager','pre_prompt_hook',
51 51 'pre_run_code_hook', 'clipboard_get']
52 52
53 53 deprecated = {'pre_run_code_hook': "a callback for the 'pre_execute' or 'pre_run_cell' event",
54 54 'late_startup_hook': "a callback for the 'shell_initialized' event",
55 55 'shutdown_hook': "the atexit module",
56 56 }
57 57
58 58 def editor(self, filename, linenum=None, wait=True):
59 59 """Open the default editor at the given filename and linenumber.
60 60
61 61 This is IPython's default editor hook, you can use it as an example to
62 62 write your own modified one. To set your own editor function as the
63 63 new editor hook, call ip.set_hook('editor',yourfunc)."""
64 64
65 65 # IPython configures a default editor at startup by reading $EDITOR from
66 66 # the environment, and falling back on vi (unix) or notepad (win32).
67 67 editor = self.editor
68 68
69 69 # marker for at which line to open the file (for existing objects)
70 70 if linenum is None or editor=='notepad':
71 71 linemark = ''
72 72 else:
73 73 linemark = '+%d' % int(linenum)
74 74
75 75 # Enclose in quotes if necessary and legal
76 76 if ' ' in editor and os.path.isfile(editor) and editor[0] != '"':
77 77 editor = '"%s"' % editor
78 78
79 79 # Call the actual editor
80 80 proc = subprocess.Popen('%s %s %s' % (editor, linemark, filename),
81 81 shell=True)
82 82 if wait and proc.wait() != 0:
83 83 raise TryNext()
84 84
85 85 import tempfile
86 86 from IPython.utils.decorators import undoc
87 87
88 88 @undoc
89 89 def fix_error_editor(self,filename,linenum,column,msg):
90 90 """DEPRECATED
91 91
92 92 Open the editor at the given filename, linenumber, column and
93 93 show an error message. This is used for correcting syntax errors.
94 94 The current implementation only has special support for the VIM editor,
95 95 and falls back on the 'editor' hook if VIM is not used.
96 96
97 97 Call ip.set_hook('fix_error_editor',yourfunc) to use your own function,
98 98 """
99 99
100 100 warnings.warn("""
101 101 `fix_error_editor` is deprecated as of IPython 6.0 and will be removed
102 102 in future versions. It appears to be used only for automatically fixing syntax
103 103 error that has been broken for a few years and has thus been removed. If you
104 104 happened to use this function and still need it please make your voice heard on
105 105 the mailing list ipython-dev@python.org , or on the GitHub Issue tracker:
106 106 https://github.com/ipython/ipython/issues/9649 """, UserWarning)
107 107
108 108 def vim_quickfix_file():
109 109 t = tempfile.NamedTemporaryFile()
110 110 t.write('%s:%d:%d:%s\n' % (filename,linenum,column,msg))
111 111 t.flush()
112 112 return t
113 113 if os.path.basename(self.editor) != 'vim':
114 114 self.hooks.editor(filename,linenum)
115 115 return
116 116 t = vim_quickfix_file()
117 117 try:
118 118 if os.system('vim --cmd "set errorformat=%f:%l:%c:%m" -q ' + t.name):
119 119 raise TryNext()
120 120 finally:
121 121 t.close()
122 122
123 123
124 124 def synchronize_with_editor(self, filename, linenum, column):
125 125 pass
126 126
127 127
128 128 class CommandChainDispatcher:
129 129 """ Dispatch calls to a chain of commands until some func can handle it
130 130
131 131 Usage: instantiate, execute "add" to add commands (with optional
132 132 priority), execute normally via f() calling mechanism.
133 133
134 134 """
135 135 def __init__(self,commands=None):
136 136 if commands is None:
137 137 self.chain = []
138 138 else:
139 139 self.chain = commands
140 140
141 141
142 142 def __call__(self,*args, **kw):
143 143 """ Command chain is called just like normal func.
144 144
145 145 This will call all funcs in chain with the same args as were given to
146 146 this function, and return the result of first func that didn't raise
147 147 TryNext"""
148 148 last_exc = TryNext()
149 149 for prio,cmd in self.chain:
150 150 #print "prio",prio,"cmd",cmd #dbg
151 151 try:
152 152 return cmd(*args, **kw)
153 153 except TryNext as exc:
154 154 last_exc = exc
155 155 # if no function will accept it, raise TryNext up to the caller
156 156 raise last_exc
157 157
158 158 def __str__(self):
159 159 return str(self.chain)
160 160
161 161 def add(self, func, priority=0):
162 162 """ Add a func to the cmd chain with given priority """
163 163 self.chain.append((priority, func))
164 164 self.chain.sort(key=lambda x: x[0])
165 165
166 166 def __iter__(self):
167 167 """ Return all objects in chain.
168 168
169 169 Handy if the objects are not callable.
170 170 """
171 171 return iter(self.chain)
172 172
173 173
174 174 def shutdown_hook(self):
175 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 180 #print "default shutdown hook ok" # dbg
181 181 return
182 182
183 183
184 184 def late_startup_hook(self):
185 185 """ Executed after ipython has been constructed and configured
186 186
187 187 """
188 188 #print "default startup hook ok" # dbg
189 189
190 190
191 191 def show_in_pager(self, data, start, screen_lines):
192 192 """ Run a string through pager """
193 193 # raising TryNext here will use the default paging functionality
194 194 raise TryNext
195 195
196 196
197 197 def pre_prompt_hook(self):
198 198 """ Run before displaying the next prompt
199 199
200 200 Use this e.g. to display output from asynchronous operations (in order
201 201 to not mess up text entry)
202 202 """
203 203
204 204 return None
205 205
206 206
207 207 def pre_run_code_hook(self):
208 208 """ Executed before running the (prefiltered) code in IPython """
209 209 return None
210 210
211 211
212 212 def clipboard_get(self):
213 213 """ Get text from the clipboard.
214 214 """
215 215 from IPython.lib.clipboard import (
216 216 osx_clipboard_get, tkinter_clipboard_get,
217 217 win32_clipboard_get
218 218 )
219 219 if sys.platform == 'win32':
220 220 chain = [win32_clipboard_get, tkinter_clipboard_get]
221 221 elif sys.platform == 'darwin':
222 222 chain = [osx_clipboard_get, tkinter_clipboard_get]
223 223 else:
224 224 chain = [tkinter_clipboard_get]
225 225 dispatcher = CommandChainDispatcher()
226 226 for func in chain:
227 227 dispatcher.add(func)
228 228 text = dispatcher()
229 229 return text
@@ -1,709 +1,709 b''
1 1 # encoding: utf-8
2 2 """
3 3 Prefiltering components.
4 4
5 5 Prefilters transform user input before it is exec'd by Python. These
6 6 transforms are used to implement additional syntax such as !ls and %magic.
7 7 """
8 8
9 9 # Copyright (c) IPython Development Team.
10 10 # Distributed under the terms of the Modified BSD License.
11 11
12 12 from keyword import iskeyword
13 13 import re
14 14
15 15 from IPython.core.autocall import IPyAutocall
16 16 from traitlets.config.configurable import Configurable
17 17 from IPython.core.inputsplitter import (
18 18 ESC_MAGIC,
19 19 ESC_QUOTE,
20 20 ESC_QUOTE2,
21 21 ESC_PAREN,
22 22 )
23 23 from IPython.core.macro import Macro
24 24 from IPython.core.splitinput import LineInfo
25 25
26 26 from traitlets import (
27 27 List, Integer, Unicode, Bool, Instance, CRegExp
28 28 )
29 29
30 30 #-----------------------------------------------------------------------------
31 31 # Global utilities, errors and constants
32 32 #-----------------------------------------------------------------------------
33 33
34 34
35 35 class PrefilterError(Exception):
36 36 pass
37 37
38 38
39 39 # RegExp to identify potential function names
40 40 re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
41 41
42 42 # RegExp to exclude strings with this start from autocalling. In
43 43 # particular, all binary operators should be excluded, so that if foo is
44 44 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
45 45 # characters '!=()' don't need to be checked for, as the checkPythonChars
46 46 # routine explicitly does so, to catch direct calls and rebindings of
47 47 # existing names.
48 48
49 49 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
50 50 # it affects the rest of the group in square brackets.
51 51 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
52 52 r'|^is |^not |^in |^and |^or ')
53 53
54 54 # try to catch also methods for stuff in lists/tuples/dicts: off
55 55 # (experimental). For this to work, the line_split regexp would need
56 56 # to be modified so it wouldn't break things at '['. That line is
57 57 # nasty enough that I shouldn't change it until I can test it _well_.
58 58 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
59 59
60 60
61 61 # Handler Check Utilities
62 62 def is_shadowed(identifier, ip):
63 63 """Is the given identifier defined in one of the namespaces which shadow
64 64 the alias and magic namespaces? Note that an identifier is different
65 65 than ifun, because it can not contain a '.' character."""
66 66 # This is much safer than calling ofind, which can change state
67 67 return (identifier in ip.user_ns \
68 68 or identifier in ip.user_global_ns \
69 69 or identifier in ip.ns_table['builtin']\
70 70 or iskeyword(identifier))
71 71
72 72
73 73 #-----------------------------------------------------------------------------
74 74 # Main Prefilter manager
75 75 #-----------------------------------------------------------------------------
76 76
77 77
78 78 class PrefilterManager(Configurable):
79 79 """Main prefilter component.
80 80
81 81 The IPython prefilter is run on all user input before it is run. The
82 82 prefilter consumes lines of input and produces transformed lines of
83 83 input.
84 84
85 The iplementation consists of two phases:
85 The implementation consists of two phases:
86 86
87 87 1. Transformers
88 88 2. Checkers and handlers
89 89
90 90 Over time, we plan on deprecating the checkers and handlers and doing
91 91 everything in the transformers.
92 92
93 93 The transformers are instances of :class:`PrefilterTransformer` and have
94 94 a single method :meth:`transform` that takes a line and returns a
95 95 transformed line. The transformation can be accomplished using any
96 96 tool, but our current ones use regular expressions for speed.
97 97
98 98 After all the transformers have been run, the line is fed to the checkers,
99 99 which are instances of :class:`PrefilterChecker`. The line is passed to
100 100 the :meth:`check` method, which either returns `None` or a
101 101 :class:`PrefilterHandler` instance. If `None` is returned, the other
102 102 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
103 103 the line is passed to the :meth:`handle` method of the returned
104 104 handler and no further checkers are tried.
105 105
106 106 Both transformers and checkers have a `priority` attribute, that determines
107 107 the order in which they are called. Smaller priorities are tried first.
108 108
109 109 Both transformers and checkers also have `enabled` attribute, which is
110 110 a boolean that determines if the instance is used.
111 111
112 112 Users or developers can change the priority or enabled attribute of
113 113 transformers or checkers, but they must call the :meth:`sort_checkers`
114 114 or :meth:`sort_transformers` method after changing the priority.
115 115 """
116 116
117 117 multi_line_specials = Bool(True).tag(config=True)
118 118 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
119 119
120 120 def __init__(self, shell=None, **kwargs):
121 121 super(PrefilterManager, self).__init__(shell=shell, **kwargs)
122 122 self.shell = shell
123 123 self.init_transformers()
124 124 self.init_handlers()
125 125 self.init_checkers()
126 126
127 127 #-------------------------------------------------------------------------
128 128 # API for managing transformers
129 129 #-------------------------------------------------------------------------
130 130
131 131 def init_transformers(self):
132 132 """Create the default transformers."""
133 133 self._transformers = []
134 134 for transformer_cls in _default_transformers:
135 135 transformer_cls(
136 136 shell=self.shell, prefilter_manager=self, parent=self
137 137 )
138 138
139 139 def sort_transformers(self):
140 140 """Sort the transformers by priority.
141 141
142 142 This must be called after the priority of a transformer is changed.
143 143 The :meth:`register_transformer` method calls this automatically.
144 144 """
145 145 self._transformers.sort(key=lambda x: x.priority)
146 146
147 147 @property
148 148 def transformers(self):
149 149 """Return a list of checkers, sorted by priority."""
150 150 return self._transformers
151 151
152 152 def register_transformer(self, transformer):
153 153 """Register a transformer instance."""
154 154 if transformer not in self._transformers:
155 155 self._transformers.append(transformer)
156 156 self.sort_transformers()
157 157
158 158 def unregister_transformer(self, transformer):
159 159 """Unregister a transformer instance."""
160 160 if transformer in self._transformers:
161 161 self._transformers.remove(transformer)
162 162
163 163 #-------------------------------------------------------------------------
164 164 # API for managing checkers
165 165 #-------------------------------------------------------------------------
166 166
167 167 def init_checkers(self):
168 168 """Create the default checkers."""
169 169 self._checkers = []
170 170 for checker in _default_checkers:
171 171 checker(
172 172 shell=self.shell, prefilter_manager=self, parent=self
173 173 )
174 174
175 175 def sort_checkers(self):
176 176 """Sort the checkers by priority.
177 177
178 178 This must be called after the priority of a checker is changed.
179 179 The :meth:`register_checker` method calls this automatically.
180 180 """
181 181 self._checkers.sort(key=lambda x: x.priority)
182 182
183 183 @property
184 184 def checkers(self):
185 185 """Return a list of checkers, sorted by priority."""
186 186 return self._checkers
187 187
188 188 def register_checker(self, checker):
189 189 """Register a checker instance."""
190 190 if checker not in self._checkers:
191 191 self._checkers.append(checker)
192 192 self.sort_checkers()
193 193
194 194 def unregister_checker(self, checker):
195 195 """Unregister a checker instance."""
196 196 if checker in self._checkers:
197 197 self._checkers.remove(checker)
198 198
199 199 #-------------------------------------------------------------------------
200 200 # API for managing handlers
201 201 #-------------------------------------------------------------------------
202 202
203 203 def init_handlers(self):
204 204 """Create the default handlers."""
205 205 self._handlers = {}
206 206 self._esc_handlers = {}
207 207 for handler in _default_handlers:
208 208 handler(
209 209 shell=self.shell, prefilter_manager=self, parent=self
210 210 )
211 211
212 212 @property
213 213 def handlers(self):
214 214 """Return a dict of all the handlers."""
215 215 return self._handlers
216 216
217 217 def register_handler(self, name, handler, esc_strings):
218 218 """Register a handler instance by name with esc_strings."""
219 219 self._handlers[name] = handler
220 220 for esc_str in esc_strings:
221 221 self._esc_handlers[esc_str] = handler
222 222
223 223 def unregister_handler(self, name, handler, esc_strings):
224 224 """Unregister a handler instance by name with esc_strings."""
225 225 try:
226 226 del self._handlers[name]
227 227 except KeyError:
228 228 pass
229 229 for esc_str in esc_strings:
230 230 h = self._esc_handlers.get(esc_str)
231 231 if h is handler:
232 232 del self._esc_handlers[esc_str]
233 233
234 234 def get_handler_by_name(self, name):
235 235 """Get a handler by its name."""
236 236 return self._handlers.get(name)
237 237
238 238 def get_handler_by_esc(self, esc_str):
239 239 """Get a handler by its escape string."""
240 240 return self._esc_handlers.get(esc_str)
241 241
242 242 #-------------------------------------------------------------------------
243 243 # Main prefiltering API
244 244 #-------------------------------------------------------------------------
245 245
246 246 def prefilter_line_info(self, line_info):
247 247 """Prefilter a line that has been converted to a LineInfo object.
248 248
249 249 This implements the checker/handler part of the prefilter pipe.
250 250 """
251 251 # print "prefilter_line_info: ", line_info
252 252 handler = self.find_handler(line_info)
253 253 return handler.handle(line_info)
254 254
255 255 def find_handler(self, line_info):
256 256 """Find a handler for the line_info by trying checkers."""
257 257 for checker in self.checkers:
258 258 if checker.enabled:
259 259 handler = checker.check(line_info)
260 260 if handler:
261 261 return handler
262 262 return self.get_handler_by_name('normal')
263 263
264 264 def transform_line(self, line, continue_prompt):
265 265 """Calls the enabled transformers in order of increasing priority."""
266 266 for transformer in self.transformers:
267 267 if transformer.enabled:
268 268 line = transformer.transform(line, continue_prompt)
269 269 return line
270 270
271 271 def prefilter_line(self, line, continue_prompt=False):
272 272 """Prefilter a single input line as text.
273 273
274 274 This method prefilters a single line of text by calling the
275 275 transformers and then the checkers/handlers.
276 276 """
277 277
278 278 # print "prefilter_line: ", line, continue_prompt
279 279 # All handlers *must* return a value, even if it's blank ('').
280 280
281 281 # save the line away in case we crash, so the post-mortem handler can
282 282 # record it
283 283 self.shell._last_input_line = line
284 284
285 285 if not line:
286 286 # Return immediately on purely empty lines, so that if the user
287 287 # previously typed some whitespace that started a continuation
288 288 # prompt, he can break out of that loop with just an empty line.
289 289 # This is how the default python prompt works.
290 290 return ''
291 291
292 292 # At this point, we invoke our transformers.
293 293 if not continue_prompt or (continue_prompt and self.multi_line_specials):
294 294 line = self.transform_line(line, continue_prompt)
295 295
296 296 # Now we compute line_info for the checkers and handlers
297 297 line_info = LineInfo(line, continue_prompt)
298 298
299 299 # the input history needs to track even empty lines
300 300 stripped = line.strip()
301 301
302 302 normal_handler = self.get_handler_by_name('normal')
303 303 if not stripped:
304 304 return normal_handler.handle(line_info)
305 305
306 306 # special handlers are only allowed for single line statements
307 307 if continue_prompt and not self.multi_line_specials:
308 308 return normal_handler.handle(line_info)
309 309
310 310 prefiltered = self.prefilter_line_info(line_info)
311 311 # print "prefiltered line: %r" % prefiltered
312 312 return prefiltered
313 313
314 314 def prefilter_lines(self, lines, continue_prompt=False):
315 315 """Prefilter multiple input lines of text.
316 316
317 317 This is the main entry point for prefiltering multiple lines of
318 318 input. This simply calls :meth:`prefilter_line` for each line of
319 319 input.
320 320
321 321 This covers cases where there are multiple lines in the user entry,
322 322 which is the case when the user goes back to a multiline history
323 323 entry and presses enter.
324 324 """
325 325 llines = lines.rstrip('\n').split('\n')
326 326 # We can get multiple lines in one shot, where multiline input 'blends'
327 327 # into one line, in cases like recalling from the readline history
328 328 # buffer. We need to make sure that in such cases, we correctly
329 329 # communicate downstream which line is first and which are continuation
330 330 # ones.
331 331 if len(llines) > 1:
332 332 out = '\n'.join([self.prefilter_line(line, lnum>0)
333 333 for lnum, line in enumerate(llines) ])
334 334 else:
335 335 out = self.prefilter_line(llines[0], continue_prompt)
336 336
337 337 return out
338 338
339 339 #-----------------------------------------------------------------------------
340 340 # Prefilter transformers
341 341 #-----------------------------------------------------------------------------
342 342
343 343
344 344 class PrefilterTransformer(Configurable):
345 345 """Transform a line of user input."""
346 346
347 347 priority = Integer(100).tag(config=True)
348 348 # Transformers don't currently use shell or prefilter_manager, but as we
349 349 # move away from checkers and handlers, they will need them.
350 350 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
351 351 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
352 352 enabled = Bool(True).tag(config=True)
353 353
354 354 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
355 355 super(PrefilterTransformer, self).__init__(
356 356 shell=shell, prefilter_manager=prefilter_manager, **kwargs
357 357 )
358 358 self.prefilter_manager.register_transformer(self)
359 359
360 360 def transform(self, line, continue_prompt):
361 361 """Transform a line, returning the new one."""
362 362 return None
363 363
364 364 def __repr__(self):
365 365 return "<%s(priority=%r, enabled=%r)>" % (
366 366 self.__class__.__name__, self.priority, self.enabled)
367 367
368 368
369 369 #-----------------------------------------------------------------------------
370 370 # Prefilter checkers
371 371 #-----------------------------------------------------------------------------
372 372
373 373
374 374 class PrefilterChecker(Configurable):
375 375 """Inspect an input line and return a handler for that line."""
376 376
377 377 priority = Integer(100).tag(config=True)
378 378 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
379 379 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
380 380 enabled = Bool(True).tag(config=True)
381 381
382 382 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
383 383 super(PrefilterChecker, self).__init__(
384 384 shell=shell, prefilter_manager=prefilter_manager, **kwargs
385 385 )
386 386 self.prefilter_manager.register_checker(self)
387 387
388 388 def check(self, line_info):
389 389 """Inspect line_info and return a handler instance or None."""
390 390 return None
391 391
392 392 def __repr__(self):
393 393 return "<%s(priority=%r, enabled=%r)>" % (
394 394 self.__class__.__name__, self.priority, self.enabled)
395 395
396 396
397 397 class EmacsChecker(PrefilterChecker):
398 398
399 399 priority = Integer(100).tag(config=True)
400 400 enabled = Bool(False).tag(config=True)
401 401
402 402 def check(self, line_info):
403 403 "Emacs ipython-mode tags certain input lines."
404 404 if line_info.line.endswith('# PYTHON-MODE'):
405 405 return self.prefilter_manager.get_handler_by_name('emacs')
406 406 else:
407 407 return None
408 408
409 409
410 410 class MacroChecker(PrefilterChecker):
411 411
412 412 priority = Integer(250).tag(config=True)
413 413
414 414 def check(self, line_info):
415 415 obj = self.shell.user_ns.get(line_info.ifun)
416 416 if isinstance(obj, Macro):
417 417 return self.prefilter_manager.get_handler_by_name('macro')
418 418 else:
419 419 return None
420 420
421 421
422 422 class IPyAutocallChecker(PrefilterChecker):
423 423
424 424 priority = Integer(300).tag(config=True)
425 425
426 426 def check(self, line_info):
427 427 "Instances of IPyAutocall in user_ns get autocalled immediately"
428 428 obj = self.shell.user_ns.get(line_info.ifun, None)
429 429 if isinstance(obj, IPyAutocall):
430 430 obj.set_ip(self.shell)
431 431 return self.prefilter_manager.get_handler_by_name('auto')
432 432 else:
433 433 return None
434 434
435 435
436 436 class AssignmentChecker(PrefilterChecker):
437 437
438 438 priority = Integer(600).tag(config=True)
439 439
440 440 def check(self, line_info):
441 441 """Check to see if user is assigning to a var for the first time, in
442 442 which case we want to avoid any sort of automagic / autocall games.
443 443
444 444 This allows users to assign to either alias or magic names true python
445 445 variables (the magic/alias systems always take second seat to true
446 446 python code). E.g. ls='hi', or ls,that=1,2"""
447 447 if line_info.the_rest:
448 448 if line_info.the_rest[0] in '=,':
449 449 return self.prefilter_manager.get_handler_by_name('normal')
450 450 else:
451 451 return None
452 452
453 453
454 454 class AutoMagicChecker(PrefilterChecker):
455 455
456 456 priority = Integer(700).tag(config=True)
457 457
458 458 def check(self, line_info):
459 459 """If the ifun is magic, and automagic is on, run it. Note: normal,
460 460 non-auto magic would already have been triggered via '%' in
461 461 check_esc_chars. This just checks for automagic. Also, before
462 462 triggering the magic handler, make sure that there is nothing in the
463 463 user namespace which could shadow it."""
464 464 if not self.shell.automagic or not self.shell.find_magic(line_info.ifun):
465 465 return None
466 466
467 467 # We have a likely magic method. Make sure we should actually call it.
468 468 if line_info.continue_prompt and not self.prefilter_manager.multi_line_specials:
469 469 return None
470 470
471 471 head = line_info.ifun.split('.',1)[0]
472 472 if is_shadowed(head, self.shell):
473 473 return None
474 474
475 475 return self.prefilter_manager.get_handler_by_name('magic')
476 476
477 477
478 478 class PythonOpsChecker(PrefilterChecker):
479 479
480 480 priority = Integer(900).tag(config=True)
481 481
482 482 def check(self, line_info):
483 483 """If the 'rest' of the line begins with a function call or pretty much
484 484 any python operator, we should simply execute the line (regardless of
485 485 whether or not there's a possible autocall expansion). This avoids
486 486 spurious (and very confusing) geattr() accesses."""
487 487 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
488 488 return self.prefilter_manager.get_handler_by_name('normal')
489 489 else:
490 490 return None
491 491
492 492
493 493 class AutocallChecker(PrefilterChecker):
494 494
495 495 priority = Integer(1000).tag(config=True)
496 496
497 497 function_name_regexp = CRegExp(re_fun_name,
498 498 help="RegExp to identify potential function names."
499 499 ).tag(config=True)
500 500 exclude_regexp = CRegExp(re_exclude_auto,
501 501 help="RegExp to exclude strings with this start from autocalling."
502 502 ).tag(config=True)
503 503
504 504 def check(self, line_info):
505 505 "Check if the initial word/function is callable and autocall is on."
506 506 if not self.shell.autocall:
507 507 return None
508 508
509 509 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
510 510 if not oinfo['found']:
511 511 return None
512 512
513 513 ignored_funs = ['b', 'f', 'r', 'u', 'br', 'rb', 'fr', 'rf']
514 514 ifun = line_info.ifun
515 515 line = line_info.line
516 516 if ifun.lower() in ignored_funs and (line.startswith(ifun + "'") or line.startswith(ifun + '"')):
517 517 return None
518 518
519 519 if callable(oinfo['obj']) \
520 520 and (not self.exclude_regexp.match(line_info.the_rest)) \
521 521 and self.function_name_regexp.match(line_info.ifun):
522 522 return self.prefilter_manager.get_handler_by_name('auto')
523 523 else:
524 524 return None
525 525
526 526
527 527 #-----------------------------------------------------------------------------
528 528 # Prefilter handlers
529 529 #-----------------------------------------------------------------------------
530 530
531 531
532 532 class PrefilterHandler(Configurable):
533 533
534 534 handler_name = Unicode('normal')
535 535 esc_strings = List([])
536 536 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True)
537 537 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True)
538 538
539 539 def __init__(self, shell=None, prefilter_manager=None, **kwargs):
540 540 super(PrefilterHandler, self).__init__(
541 541 shell=shell, prefilter_manager=prefilter_manager, **kwargs
542 542 )
543 543 self.prefilter_manager.register_handler(
544 544 self.handler_name,
545 545 self,
546 546 self.esc_strings
547 547 )
548 548
549 549 def handle(self, line_info):
550 550 # print "normal: ", line_info
551 551 """Handle normal input lines. Use as a template for handlers."""
552 552
553 553 # With autoindent on, we need some way to exit the input loop, and I
554 554 # don't want to force the user to have to backspace all the way to
555 555 # clear the line. The rule will be in this case, that either two
556 556 # lines of pure whitespace in a row, or a line of pure whitespace but
557 557 # of a size different to the indent level, will exit the input loop.
558 558 line = line_info.line
559 559 continue_prompt = line_info.continue_prompt
560 560
561 561 if (continue_prompt and
562 562 self.shell.autoindent and
563 563 line.isspace() and
564 564 0 < abs(len(line) - self.shell.indent_current_nsp) <= 2):
565 565 line = ''
566 566
567 567 return line
568 568
569 569 def __str__(self):
570 570 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
571 571
572 572
573 573 class MacroHandler(PrefilterHandler):
574 574 handler_name = Unicode("macro")
575 575
576 576 def handle(self, line_info):
577 577 obj = self.shell.user_ns.get(line_info.ifun)
578 578 pre_space = line_info.pre_whitespace
579 579 line_sep = "\n" + pre_space
580 580 return pre_space + line_sep.join(obj.value.splitlines())
581 581
582 582
583 583 class MagicHandler(PrefilterHandler):
584 584
585 585 handler_name = Unicode('magic')
586 586 esc_strings = List([ESC_MAGIC])
587 587
588 588 def handle(self, line_info):
589 589 """Execute magic functions."""
590 590 ifun = line_info.ifun
591 591 the_rest = line_info.the_rest
592 592 #Prepare arguments for get_ipython().run_line_magic(magic_name, magic_args)
593 593 t_arg_s = ifun + " " + the_rest
594 594 t_magic_name, _, t_magic_arg_s = t_arg_s.partition(' ')
595 595 t_magic_name = t_magic_name.lstrip(ESC_MAGIC)
596 596 cmd = '%sget_ipython().run_line_magic(%r, %r)' % (line_info.pre_whitespace, t_magic_name, t_magic_arg_s)
597 597 return cmd
598 598
599 599
600 600 class AutoHandler(PrefilterHandler):
601 601
602 602 handler_name = Unicode('auto')
603 603 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
604 604
605 605 def handle(self, line_info):
606 606 """Handle lines which can be auto-executed, quoting if requested."""
607 607 line = line_info.line
608 608 ifun = line_info.ifun
609 609 the_rest = line_info.the_rest
610 610 esc = line_info.esc
611 611 continue_prompt = line_info.continue_prompt
612 612 obj = line_info.ofind(self.shell)['obj']
613 613
614 614 # This should only be active for single-line input!
615 615 if continue_prompt:
616 616 return line
617 617
618 618 force_auto = isinstance(obj, IPyAutocall)
619 619
620 620 # User objects sometimes raise exceptions on attribute access other
621 621 # than AttributeError (we've seen it in the past), so it's safest to be
622 622 # ultra-conservative here and catch all.
623 623 try:
624 624 auto_rewrite = obj.rewrite
625 625 except Exception:
626 626 auto_rewrite = True
627 627
628 628 if esc == ESC_QUOTE:
629 629 # Auto-quote splitting on whitespace
630 630 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
631 631 elif esc == ESC_QUOTE2:
632 632 # Auto-quote whole string
633 633 newcmd = '%s("%s")' % (ifun,the_rest)
634 634 elif esc == ESC_PAREN:
635 635 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
636 636 else:
637 637 # Auto-paren.
638 638 if force_auto:
639 639 # Don't rewrite if it is already a call.
640 640 do_rewrite = not the_rest.startswith('(')
641 641 else:
642 642 if not the_rest:
643 643 # We only apply it to argument-less calls if the autocall
644 644 # parameter is set to 2.
645 645 do_rewrite = (self.shell.autocall >= 2)
646 646 elif the_rest.startswith('[') and hasattr(obj, '__getitem__'):
647 647 # Don't autocall in this case: item access for an object
648 648 # which is BOTH callable and implements __getitem__.
649 649 do_rewrite = False
650 650 else:
651 651 do_rewrite = True
652 652
653 653 # Figure out the rewritten command
654 654 if do_rewrite:
655 655 if the_rest.endswith(';'):
656 656 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
657 657 else:
658 658 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
659 659 else:
660 660 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
661 661 return normal_handler.handle(line_info)
662 662
663 663 # Display the rewritten call
664 664 if auto_rewrite:
665 665 self.shell.auto_rewrite_input(newcmd)
666 666
667 667 return newcmd
668 668
669 669
670 670 class EmacsHandler(PrefilterHandler):
671 671
672 672 handler_name = Unicode('emacs')
673 673 esc_strings = List([])
674 674
675 675 def handle(self, line_info):
676 676 """Handle input lines marked by python-mode."""
677 677
678 678 # Currently, nothing is done. Later more functionality can be added
679 679 # here if needed.
680 680
681 681 # The input cache shouldn't be updated
682 682 return line_info.line
683 683
684 684
685 685 #-----------------------------------------------------------------------------
686 686 # Defaults
687 687 #-----------------------------------------------------------------------------
688 688
689 689
690 690 _default_transformers = [
691 691 ]
692 692
693 693 _default_checkers = [
694 694 EmacsChecker,
695 695 MacroChecker,
696 696 IPyAutocallChecker,
697 697 AssignmentChecker,
698 698 AutoMagicChecker,
699 699 PythonOpsChecker,
700 700 AutocallChecker
701 701 ]
702 702
703 703 _default_handlers = [
704 704 PrefilterHandler,
705 705 MacroHandler,
706 706 MagicHandler,
707 707 AutoHandler,
708 708 EmacsHandler
709 709 ]
@@ -1,871 +1,871 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Python advanced pretty printer. This pretty printer is intended to
4 4 replace the old `pprint` python module which does not allow developers
5 5 to provide their own pretty print callbacks.
6 6
7 7 This module is based on ruby's `prettyprint.rb` library by `Tanaka Akira`.
8 8
9 9
10 10 Example Usage
11 11 -------------
12 12
13 13 To directly print the representation of an object use `pprint`::
14 14
15 15 from pretty import pprint
16 16 pprint(complex_object)
17 17
18 18 To get a string of the output use `pretty`::
19 19
20 20 from pretty import pretty
21 21 string = pretty(complex_object)
22 22
23 23
24 24 Extending
25 25 ---------
26 26
27 27 The pretty library allows developers to add pretty printing rules for their
28 28 own objects. This process is straightforward. All you have to do is to
29 29 add a `_repr_pretty_` method to your object and call the methods on the
30 30 pretty printer passed::
31 31
32 32 class MyObject(object):
33 33
34 34 def _repr_pretty_(self, p, cycle):
35 35 ...
36 36
37 37 Here is an example implementation of a `_repr_pretty_` method for a list
38 38 subclass::
39 39
40 40 class MyList(list):
41 41
42 42 def _repr_pretty_(self, p, cycle):
43 43 if cycle:
44 44 p.text('MyList(...)')
45 45 else:
46 46 with p.group(8, 'MyList([', '])'):
47 47 for idx, item in enumerate(self):
48 48 if idx:
49 49 p.text(',')
50 50 p.breakable()
51 51 p.pretty(item)
52 52
53 53 The `cycle` parameter is `True` if pretty detected a cycle. You *have* to
54 54 react to that or the result is an infinite loop. `p.text()` just adds
55 55 non breaking text to the output, `p.breakable()` either adds a whitespace
56 56 or breaks here. If you pass it an argument it's used instead of the
57 57 default space. `p.pretty` prettyprints another object using the pretty print
58 58 method.
59 59
60 60 The first parameter to the `group` function specifies the extra indentation
61 61 of the next line. In this example the next item will either be on the same
62 62 line (if the items are short enough) or aligned with the right edge of the
63 63 opening bracket of `MyList`.
64 64
65 65 If you just want to indent something you can use the group function
66 66 without open / close parameters. You can also use this code::
67 67
68 68 with p.indent(2):
69 69 ...
70 70
71 71 Inheritance diagram:
72 72
73 73 .. inheritance-diagram:: IPython.lib.pretty
74 74 :parts: 3
75 75
76 76 :copyright: 2007 by Armin Ronacher.
77 77 Portions (c) 2009 by Robert Kern.
78 78 :license: BSD License.
79 79 """
80 80
81 81 from contextlib import contextmanager
82 82 import datetime
83 83 import os
84 84 import re
85 85 import sys
86 86 import types
87 87 from collections import deque
88 88 from inspect import signature
89 89 from io import StringIO
90 90 from warnings import warn
91 91
92 92 from IPython.utils.decorators import undoc
93 93 from IPython.utils.py3compat import PYPY
94 94
95 95 __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter',
96 96 'for_type', 'for_type_by_name']
97 97
98 98
99 99 MAX_SEQ_LENGTH = 1000
100 100 # The language spec says that dicts preserve order from 3.7, but CPython
101 101 # does so from 3.6, so it seems likely that people will expect that.
102 102 DICT_IS_ORDERED = sys.version_info >= (3, 6)
103 103 _re_pattern_type = type(re.compile(''))
104 104
105 105 def _safe_getattr(obj, attr, default=None):
106 106 """Safe version of getattr.
107 107
108 108 Same as getattr, but will return ``default`` on any Exception,
109 109 rather than raising.
110 110 """
111 111 try:
112 112 return getattr(obj, attr, default)
113 113 except Exception:
114 114 return default
115 115
116 116 @undoc
117 117 class CUnicodeIO(StringIO):
118 118 def __init__(self, *args, **kwargs):
119 119 super().__init__(*args, **kwargs)
120 120 warn(("CUnicodeIO is deprecated since IPython 6.0. "
121 121 "Please use io.StringIO instead."),
122 122 DeprecationWarning, stacklevel=2)
123 123
124 124 def _sorted_for_pprint(items):
125 125 """
126 126 Sort the given items for pretty printing. Since some predictable
127 127 sorting is better than no sorting at all, we sort on the string
128 128 representation if normal sorting fails.
129 129 """
130 130 items = list(items)
131 131 try:
132 132 return sorted(items)
133 133 except Exception:
134 134 try:
135 135 return sorted(items, key=str)
136 136 except Exception:
137 137 return items
138 138
139 139 def pretty(obj, verbose=False, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
140 140 """
141 141 Pretty print the object's representation.
142 142 """
143 143 stream = StringIO()
144 144 printer = RepresentationPrinter(stream, verbose, max_width, newline, max_seq_length=max_seq_length)
145 145 printer.pretty(obj)
146 146 printer.flush()
147 147 return stream.getvalue()
148 148
149 149
150 150 def pprint(obj, verbose=False, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
151 151 """
152 152 Like `pretty` but print to stdout.
153 153 """
154 154 printer = RepresentationPrinter(sys.stdout, verbose, max_width, newline, max_seq_length=max_seq_length)
155 155 printer.pretty(obj)
156 156 printer.flush()
157 157 sys.stdout.write(newline)
158 158 sys.stdout.flush()
159 159
160 160 class _PrettyPrinterBase(object):
161 161
162 162 @contextmanager
163 163 def indent(self, indent):
164 164 """with statement support for indenting/dedenting."""
165 165 self.indentation += indent
166 166 try:
167 167 yield
168 168 finally:
169 169 self.indentation -= indent
170 170
171 171 @contextmanager
172 172 def group(self, indent=0, open='', close=''):
173 173 """like begin_group / end_group but for the with statement."""
174 174 self.begin_group(indent, open)
175 175 try:
176 176 yield
177 177 finally:
178 178 self.end_group(indent, close)
179 179
180 180 class PrettyPrinter(_PrettyPrinterBase):
181 181 """
182 182 Baseclass for the `RepresentationPrinter` prettyprinter that is used to
183 183 generate pretty reprs of objects. Contrary to the `RepresentationPrinter`
184 184 this printer knows nothing about the default pprinters or the `_repr_pretty_`
185 185 callback method.
186 186 """
187 187
188 188 def __init__(self, output, max_width=79, newline='\n', max_seq_length=MAX_SEQ_LENGTH):
189 189 self.output = output
190 190 self.max_width = max_width
191 191 self.newline = newline
192 192 self.max_seq_length = max_seq_length
193 193 self.output_width = 0
194 194 self.buffer_width = 0
195 195 self.buffer = deque()
196 196
197 197 root_group = Group(0)
198 198 self.group_stack = [root_group]
199 199 self.group_queue = GroupQueue(root_group)
200 200 self.indentation = 0
201 201
202 202 def _break_outer_groups(self):
203 203 while self.max_width < self.output_width + self.buffer_width:
204 204 group = self.group_queue.deq()
205 205 if not group:
206 206 return
207 207 while group.breakables:
208 208 x = self.buffer.popleft()
209 209 self.output_width = x.output(self.output, self.output_width)
210 210 self.buffer_width -= x.width
211 211 while self.buffer and isinstance(self.buffer[0], Text):
212 212 x = self.buffer.popleft()
213 213 self.output_width = x.output(self.output, self.output_width)
214 214 self.buffer_width -= x.width
215 215
216 216 def text(self, obj):
217 217 """Add literal text to the output."""
218 218 width = len(obj)
219 219 if self.buffer:
220 220 text = self.buffer[-1]
221 221 if not isinstance(text, Text):
222 222 text = Text()
223 223 self.buffer.append(text)
224 224 text.add(obj, width)
225 225 self.buffer_width += width
226 226 self._break_outer_groups()
227 227 else:
228 228 self.output.write(obj)
229 229 self.output_width += width
230 230
231 231 def breakable(self, sep=' '):
232 232 """
233 233 Add a breakable separator to the output. This does not mean that it
234 234 will automatically break here. If no breaking on this position takes
235 235 place the `sep` is inserted which default to one space.
236 236 """
237 237 width = len(sep)
238 238 group = self.group_stack[-1]
239 239 if group.want_break:
240 240 self.flush()
241 241 self.output.write(self.newline)
242 242 self.output.write(' ' * self.indentation)
243 243 self.output_width = self.indentation
244 244 self.buffer_width = 0
245 245 else:
246 246 self.buffer.append(Breakable(sep, width, self))
247 247 self.buffer_width += width
248 248 self._break_outer_groups()
249 249
250 250 def break_(self):
251 251 """
252 252 Explicitly insert a newline into the output, maintaining correct indentation.
253 253 """
254 254 self.flush()
255 255 self.output.write(self.newline)
256 256 self.output.write(' ' * self.indentation)
257 257 self.output_width = self.indentation
258 258 self.buffer_width = 0
259 259
260 260
261 261 def begin_group(self, indent=0, open=''):
262 262 """
263 263 Begin a group. If you want support for python < 2.5 which doesn't has
264 264 the with statement this is the preferred way:
265 265
266 266 p.begin_group(1, '{')
267 267 ...
268 268 p.end_group(1, '}')
269 269
270 270 The python 2.5 expression would be this:
271 271
272 272 with p.group(1, '{', '}'):
273 273 ...
274 274
275 275 The first parameter specifies the indentation for the next line (usually
276 276 the width of the opening text), the second the opening text. All
277 277 parameters are optional.
278 278 """
279 279 if open:
280 280 self.text(open)
281 281 group = Group(self.group_stack[-1].depth + 1)
282 282 self.group_stack.append(group)
283 283 self.group_queue.enq(group)
284 284 self.indentation += indent
285 285
286 286 def _enumerate(self, seq):
287 287 """like enumerate, but with an upper limit on the number of items"""
288 288 for idx, x in enumerate(seq):
289 289 if self.max_seq_length and idx >= self.max_seq_length:
290 290 self.text(',')
291 291 self.breakable()
292 292 self.text('...')
293 293 return
294 294 yield idx, x
295 295
296 296 def end_group(self, dedent=0, close=''):
297 297 """End a group. See `begin_group` for more details."""
298 298 self.indentation -= dedent
299 299 group = self.group_stack.pop()
300 300 if not group.breakables:
301 301 self.group_queue.remove(group)
302 302 if close:
303 303 self.text(close)
304 304
305 305 def flush(self):
306 306 """Flush data that is left in the buffer."""
307 307 for data in self.buffer:
308 308 self.output_width += data.output(self.output, self.output_width)
309 309 self.buffer.clear()
310 310 self.buffer_width = 0
311 311
312 312
313 313 def _get_mro(obj_class):
314 314 """ Get a reasonable method resolution order of a class and its superclasses
315 315 for both old-style and new-style classes.
316 316 """
317 317 if not hasattr(obj_class, '__mro__'):
318 318 # Old-style class. Mix in object to make a fake new-style class.
319 319 try:
320 320 obj_class = type(obj_class.__name__, (obj_class, object), {})
321 321 except TypeError:
322 322 # Old-style extension type that does not descend from object.
323 323 # FIXME: try to construct a more thorough MRO.
324 324 mro = [obj_class]
325 325 else:
326 326 mro = obj_class.__mro__[1:-1]
327 327 else:
328 328 mro = obj_class.__mro__
329 329 return mro
330 330
331 331
332 332 class RepresentationPrinter(PrettyPrinter):
333 333 """
334 334 Special pretty printer that has a `pretty` method that calls the pretty
335 335 printer for a python object.
336 336
337 337 This class stores processing data on `self` so you must *never* use
338 338 this class in a threaded environment. Always lock it or reinstanciate
339 339 it.
340 340
341 341 Instances also have a verbose flag callbacks can access to control their
342 342 output. For example the default instance repr prints all attributes and
343 343 methods that are not prefixed by an underscore if the printer is in
344 344 verbose mode.
345 345 """
346 346
347 347 def __init__(self, output, verbose=False, max_width=79, newline='\n',
348 348 singleton_pprinters=None, type_pprinters=None, deferred_pprinters=None,
349 349 max_seq_length=MAX_SEQ_LENGTH):
350 350
351 351 PrettyPrinter.__init__(self, output, max_width, newline, max_seq_length=max_seq_length)
352 352 self.verbose = verbose
353 353 self.stack = []
354 354 if singleton_pprinters is None:
355 355 singleton_pprinters = _singleton_pprinters.copy()
356 356 self.singleton_pprinters = singleton_pprinters
357 357 if type_pprinters is None:
358 358 type_pprinters = _type_pprinters.copy()
359 359 self.type_pprinters = type_pprinters
360 360 if deferred_pprinters is None:
361 361 deferred_pprinters = _deferred_type_pprinters.copy()
362 362 self.deferred_pprinters = deferred_pprinters
363 363
364 364 def pretty(self, obj):
365 365 """Pretty print the given object."""
366 366 obj_id = id(obj)
367 367 cycle = obj_id in self.stack
368 368 self.stack.append(obj_id)
369 369 self.begin_group()
370 370 try:
371 371 obj_class = _safe_getattr(obj, '__class__', None) or type(obj)
372 372 # First try to find registered singleton printers for the type.
373 373 try:
374 374 printer = self.singleton_pprinters[obj_id]
375 375 except (TypeError, KeyError):
376 376 pass
377 377 else:
378 378 return printer(obj, self, cycle)
379 379 # Next walk the mro and check for either:
380 380 # 1) a registered printer
381 381 # 2) a _repr_pretty_ method
382 382 for cls in _get_mro(obj_class):
383 383 if cls in self.type_pprinters:
384 384 # printer registered in self.type_pprinters
385 385 return self.type_pprinters[cls](obj, self, cycle)
386 386 else:
387 387 # deferred printer
388 388 printer = self._in_deferred_types(cls)
389 389 if printer is not None:
390 390 return printer(obj, self, cycle)
391 391 else:
392 392 # Finally look for special method names.
393 393 # Some objects automatically create any requested
394 394 # attribute. Try to ignore most of them by checking for
395 395 # callability.
396 396 if '_repr_pretty_' in cls.__dict__:
397 397 meth = cls._repr_pretty_
398 398 if callable(meth):
399 399 return meth(obj, self, cycle)
400 400 if cls is not object \
401 401 and callable(cls.__dict__.get('__repr__')):
402 402 return _repr_pprint(obj, self, cycle)
403 403
404 404 return _default_pprint(obj, self, cycle)
405 405 finally:
406 406 self.end_group()
407 407 self.stack.pop()
408 408
409 409 def _in_deferred_types(self, cls):
410 410 """
411 411 Check if the given class is specified in the deferred type registry.
412 412
413 413 Returns the printer from the registry if it exists, and None if the
414 414 class is not in the registry. Successful matches will be moved to the
415 415 regular type registry for future use.
416 416 """
417 417 mod = _safe_getattr(cls, '__module__', None)
418 418 name = _safe_getattr(cls, '__name__', None)
419 419 key = (mod, name)
420 420 printer = None
421 421 if key in self.deferred_pprinters:
422 422 # Move the printer over to the regular registry.
423 423 printer = self.deferred_pprinters.pop(key)
424 424 self.type_pprinters[cls] = printer
425 425 return printer
426 426
427 427
428 428 class Printable(object):
429 429
430 430 def output(self, stream, output_width):
431 431 return output_width
432 432
433 433
434 434 class Text(Printable):
435 435
436 436 def __init__(self):
437 437 self.objs = []
438 438 self.width = 0
439 439
440 440 def output(self, stream, output_width):
441 441 for obj in self.objs:
442 442 stream.write(obj)
443 443 return output_width + self.width
444 444
445 445 def add(self, obj, width):
446 446 self.objs.append(obj)
447 447 self.width += width
448 448
449 449
450 450 class Breakable(Printable):
451 451
452 452 def __init__(self, seq, width, pretty):
453 453 self.obj = seq
454 454 self.width = width
455 455 self.pretty = pretty
456 456 self.indentation = pretty.indentation
457 457 self.group = pretty.group_stack[-1]
458 458 self.group.breakables.append(self)
459 459
460 460 def output(self, stream, output_width):
461 461 self.group.breakables.popleft()
462 462 if self.group.want_break:
463 463 stream.write(self.pretty.newline)
464 464 stream.write(' ' * self.indentation)
465 465 return self.indentation
466 466 if not self.group.breakables:
467 467 self.pretty.group_queue.remove(self.group)
468 468 stream.write(self.obj)
469 469 return output_width + self.width
470 470
471 471
472 472 class Group(Printable):
473 473
474 474 def __init__(self, depth):
475 475 self.depth = depth
476 476 self.breakables = deque()
477 477 self.want_break = False
478 478
479 479
480 480 class GroupQueue(object):
481 481
482 482 def __init__(self, *groups):
483 483 self.queue = []
484 484 for group in groups:
485 485 self.enq(group)
486 486
487 487 def enq(self, group):
488 488 depth = group.depth
489 489 while depth > len(self.queue) - 1:
490 490 self.queue.append([])
491 491 self.queue[depth].append(group)
492 492
493 493 def deq(self):
494 494 for stack in self.queue:
495 495 for idx, group in enumerate(reversed(stack)):
496 496 if group.breakables:
497 497 del stack[idx]
498 498 group.want_break = True
499 499 return group
500 500 for group in stack:
501 501 group.want_break = True
502 502 del stack[:]
503 503
504 504 def remove(self, group):
505 505 try:
506 506 self.queue[group.depth].remove(group)
507 507 except ValueError:
508 508 pass
509 509
510 510
511 511 def _default_pprint(obj, p, cycle):
512 512 """
513 513 The default print function. Used if an object does not provide one and
514 514 it's none of the builtin objects.
515 515 """
516 516 klass = _safe_getattr(obj, '__class__', None) or type(obj)
517 517 if _safe_getattr(klass, '__repr__', None) is not object.__repr__:
518 518 # A user-provided repr. Find newlines and replace them with p.break_()
519 519 _repr_pprint(obj, p, cycle)
520 520 return
521 521 p.begin_group(1, '<')
522 522 p.pretty(klass)
523 523 p.text(' at 0x%x' % id(obj))
524 524 if cycle:
525 525 p.text(' ...')
526 526 elif p.verbose:
527 527 first = True
528 528 for key in dir(obj):
529 529 if not key.startswith('_'):
530 530 try:
531 531 value = getattr(obj, key)
532 532 except AttributeError:
533 533 continue
534 534 if isinstance(value, types.MethodType):
535 535 continue
536 536 if not first:
537 537 p.text(',')
538 538 p.breakable()
539 539 p.text(key)
540 540 p.text('=')
541 541 step = len(key) + 1
542 542 p.indentation += step
543 543 p.pretty(value)
544 544 p.indentation -= step
545 545 first = False
546 546 p.end_group(1, '>')
547 547
548 548
549 549 def _seq_pprinter_factory(start, end):
550 550 """
551 551 Factory that returns a pprint function useful for sequences. Used by
552 552 the default pprint for tuples, dicts, and lists.
553 553 """
554 554 def inner(obj, p, cycle):
555 555 if cycle:
556 556 return p.text(start + '...' + end)
557 557 step = len(start)
558 558 p.begin_group(step, start)
559 559 for idx, x in p._enumerate(obj):
560 560 if idx:
561 561 p.text(',')
562 562 p.breakable()
563 563 p.pretty(x)
564 564 if len(obj) == 1 and type(obj) is tuple:
565 565 # Special case for 1-item tuples.
566 566 p.text(',')
567 567 p.end_group(step, end)
568 568 return inner
569 569
570 570
571 571 def _set_pprinter_factory(start, end):
572 572 """
573 573 Factory that returns a pprint function useful for sets and frozensets.
574 574 """
575 575 def inner(obj, p, cycle):
576 576 if cycle:
577 577 return p.text(start + '...' + end)
578 578 if len(obj) == 0:
579 579 # Special case.
580 580 p.text(type(obj).__name__ + '()')
581 581 else:
582 582 step = len(start)
583 583 p.begin_group(step, start)
584 584 # Like dictionary keys, we will try to sort the items if there aren't too many
585 585 if not (p.max_seq_length and len(obj) >= p.max_seq_length):
586 586 items = _sorted_for_pprint(obj)
587 587 else:
588 588 items = obj
589 589 for idx, x in p._enumerate(items):
590 590 if idx:
591 591 p.text(',')
592 592 p.breakable()
593 593 p.pretty(x)
594 594 p.end_group(step, end)
595 595 return inner
596 596
597 597
598 598 def _dict_pprinter_factory(start, end):
599 599 """
600 600 Factory that returns a pprint function used by the default pprint of
601 601 dicts and dict proxies.
602 602 """
603 603 def inner(obj, p, cycle):
604 604 if cycle:
605 605 return p.text('{...}')
606 606 step = len(start)
607 607 p.begin_group(step, start)
608 608 keys = obj.keys()
609 609 # if dict isn't large enough to be truncated, sort keys before displaying
610 610 # From Python 3.7, dicts preserve order by definition, so we don't sort.
611 611 if not DICT_IS_ORDERED \
612 612 and not (p.max_seq_length and len(obj) >= p.max_seq_length):
613 613 keys = _sorted_for_pprint(keys)
614 614 for idx, key in p._enumerate(keys):
615 615 if idx:
616 616 p.text(',')
617 617 p.breakable()
618 618 p.pretty(key)
619 619 p.text(': ')
620 620 p.pretty(obj[key])
621 621 p.end_group(step, end)
622 622 return inner
623 623
624 624
625 625 def _super_pprint(obj, p, cycle):
626 626 """The pprint for the super type."""
627 627 p.begin_group(8, '<super: ')
628 628 p.pretty(obj.__thisclass__)
629 629 p.text(',')
630 630 p.breakable()
631 631 if PYPY: # In PyPy, super() objects don't have __self__ attributes
632 632 dself = obj.__repr__.__self__
633 633 p.pretty(None if dself is obj else dself)
634 634 else:
635 635 p.pretty(obj.__self__)
636 636 p.end_group(8, '>')
637 637
638 638
639 639 def _re_pattern_pprint(obj, p, cycle):
640 640 """The pprint function for regular expression patterns."""
641 641 p.text('re.compile(')
642 642 pattern = repr(obj.pattern)
643 643 if pattern[:1] in 'uU':
644 644 pattern = pattern[1:]
645 645 prefix = 'ur'
646 646 else:
647 647 prefix = 'r'
648 648 pattern = prefix + pattern.replace('\\\\', '\\')
649 649 p.text(pattern)
650 650 if obj.flags:
651 651 p.text(',')
652 652 p.breakable()
653 653 done_one = False
654 654 for flag in ('TEMPLATE', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL',
655 655 'UNICODE', 'VERBOSE', 'DEBUG'):
656 656 if obj.flags & getattr(re, flag):
657 657 if done_one:
658 658 p.text('|')
659 659 p.text('re.' + flag)
660 660 done_one = True
661 661 p.text(')')
662 662
663 663
664 664 def _type_pprint(obj, p, cycle):
665 665 """The pprint for classes and types."""
666 666 # Heap allocated types might not have the module attribute,
667 667 # and others may set it to None.
668 668
669 669 # Checks for a __repr__ override in the metaclass. Can't compare the
670 670 # type(obj).__repr__ directly because in PyPy the representation function
671 671 # inherited from type isn't the same type.__repr__
672 672 if [m for m in _get_mro(type(obj)) if "__repr__" in vars(m)][:1] != [type]:
673 673 _repr_pprint(obj, p, cycle)
674 674 return
675 675
676 676 mod = _safe_getattr(obj, '__module__', None)
677 677 try:
678 678 name = obj.__qualname__
679 679 if not isinstance(name, str):
680 680 # This can happen if the type implements __qualname__ as a property
681 681 # or other descriptor in Python 2.
682 682 raise Exception("Try __name__")
683 683 except Exception:
684 684 name = obj.__name__
685 685 if not isinstance(name, str):
686 686 name = '<unknown type>'
687 687
688 688 if mod in (None, '__builtin__', 'builtins', 'exceptions'):
689 689 p.text(name)
690 690 else:
691 691 p.text(mod + '.' + name)
692 692
693 693
694 694 def _repr_pprint(obj, p, cycle):
695 695 """A pprint that just redirects to the normal repr function."""
696 696 # Find newlines and replace them with p.break_()
697 697 output = repr(obj)
698 698 for idx,output_line in enumerate(output.splitlines()):
699 699 if idx:
700 700 p.break_()
701 701 p.text(output_line)
702 702
703 703
704 704 def _function_pprint(obj, p, cycle):
705 705 """Base pprint for all functions and builtin functions."""
706 706 name = _safe_getattr(obj, '__qualname__', obj.__name__)
707 707 mod = obj.__module__
708 708 if mod and mod not in ('__builtin__', 'builtins', 'exceptions'):
709 709 name = mod + '.' + name
710 710 try:
711 711 func_def = name + str(signature(obj))
712 712 except ValueError:
713 713 func_def = name
714 714 p.text('<function %s>' % func_def)
715 715
716 716
717 717 def _exception_pprint(obj, p, cycle):
718 718 """Base pprint for all exceptions."""
719 719 name = getattr(obj.__class__, '__qualname__', obj.__class__.__name__)
720 720 if obj.__class__.__module__ not in ('exceptions', 'builtins'):
721 721 name = '%s.%s' % (obj.__class__.__module__, name)
722 722 step = len(name) + 1
723 723 p.begin_group(step, name + '(')
724 724 for idx, arg in enumerate(getattr(obj, 'args', ())):
725 725 if idx:
726 726 p.text(',')
727 727 p.breakable()
728 728 p.pretty(arg)
729 729 p.end_group(step, ')')
730 730
731 731
732 732 #: the exception base
733 733 try:
734 734 _exception_base = BaseException
735 735 except NameError:
736 736 _exception_base = Exception
737 737
738 738
739 739 #: printers for builtin types
740 740 _type_pprinters = {
741 741 int: _repr_pprint,
742 742 float: _repr_pprint,
743 743 str: _repr_pprint,
744 744 tuple: _seq_pprinter_factory('(', ')'),
745 745 list: _seq_pprinter_factory('[', ']'),
746 746 dict: _dict_pprinter_factory('{', '}'),
747 747 set: _set_pprinter_factory('{', '}'),
748 748 frozenset: _set_pprinter_factory('frozenset({', '})'),
749 749 super: _super_pprint,
750 750 _re_pattern_type: _re_pattern_pprint,
751 751 type: _type_pprint,
752 752 types.FunctionType: _function_pprint,
753 753 types.BuiltinFunctionType: _function_pprint,
754 754 types.MethodType: _repr_pprint,
755 755 datetime.datetime: _repr_pprint,
756 756 datetime.timedelta: _repr_pprint,
757 757 _exception_base: _exception_pprint
758 758 }
759 759
760 760 # render os.environ like a dict
761 761 _env_type = type(os.environ)
762 762 # future-proof in case os.environ becomes a plain dict?
763 763 if _env_type is not dict:
764 764 _type_pprinters[_env_type] = _dict_pprinter_factory('environ{', '}')
765 765
766 766 try:
767 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 769 _type_pprinters.setdefault(types.DictProxyType,
770 770 _dict_pprinter_factory('dict_proxy({', '})'))
771 771 _type_pprinters[types.ClassType] = _type_pprint
772 772 _type_pprinters[types.SliceType] = _repr_pprint
773 773 except AttributeError: # Python 3
774 774 _type_pprinters[types.MappingProxyType] = \
775 775 _dict_pprinter_factory('mappingproxy({', '})')
776 776 _type_pprinters[slice] = _repr_pprint
777 777
778 778 try:
779 779 _type_pprinters[long] = _repr_pprint
780 780 _type_pprinters[unicode] = _repr_pprint
781 781 except NameError:
782 782 _type_pprinters[range] = _repr_pprint
783 783 _type_pprinters[bytes] = _repr_pprint
784 784
785 785 #: printers for types specified by name
786 786 _deferred_type_pprinters = {
787 787 }
788 788
789 789 def for_type(typ, func):
790 790 """
791 791 Add a pretty printer for a given type.
792 792 """
793 793 oldfunc = _type_pprinters.get(typ, None)
794 794 if func is not None:
795 795 # To support easy restoration of old pprinters, we need to ignore Nones.
796 796 _type_pprinters[typ] = func
797 797 return oldfunc
798 798
799 799 def for_type_by_name(type_module, type_name, func):
800 800 """
801 801 Add a pretty printer for a type specified by the module and name of a type
802 802 rather than the type object itself.
803 803 """
804 804 key = (type_module, type_name)
805 805 oldfunc = _deferred_type_pprinters.get(key, None)
806 806 if func is not None:
807 807 # To support easy restoration of old pprinters, we need to ignore Nones.
808 808 _deferred_type_pprinters[key] = func
809 809 return oldfunc
810 810
811 811
812 812 #: printers for the default singletons
813 813 _singleton_pprinters = dict.fromkeys(map(id, [None, True, False, Ellipsis,
814 814 NotImplemented]), _repr_pprint)
815 815
816 816
817 817 def _defaultdict_pprint(obj, p, cycle):
818 818 name = obj.__class__.__name__
819 819 with p.group(len(name) + 1, name + '(', ')'):
820 820 if cycle:
821 821 p.text('...')
822 822 else:
823 823 p.pretty(obj.default_factory)
824 824 p.text(',')
825 825 p.breakable()
826 826 p.pretty(dict(obj))
827 827
828 828 def _ordereddict_pprint(obj, p, cycle):
829 829 name = obj.__class__.__name__
830 830 with p.group(len(name) + 1, name + '(', ')'):
831 831 if cycle:
832 832 p.text('...')
833 833 elif len(obj):
834 834 p.pretty(list(obj.items()))
835 835
836 836 def _deque_pprint(obj, p, cycle):
837 837 name = obj.__class__.__name__
838 838 with p.group(len(name) + 1, name + '(', ')'):
839 839 if cycle:
840 840 p.text('...')
841 841 else:
842 842 p.pretty(list(obj))
843 843
844 844
845 845 def _counter_pprint(obj, p, cycle):
846 846 name = obj.__class__.__name__
847 847 with p.group(len(name) + 1, name + '(', ')'):
848 848 if cycle:
849 849 p.text('...')
850 850 elif len(obj):
851 851 p.pretty(dict(obj))
852 852
853 853 for_type_by_name('collections', 'defaultdict', _defaultdict_pprint)
854 854 for_type_by_name('collections', 'OrderedDict', _ordereddict_pprint)
855 855 for_type_by_name('collections', 'deque', _deque_pprint)
856 856 for_type_by_name('collections', 'Counter', _counter_pprint)
857 857
858 858 if __name__ == '__main__':
859 859 from random import randrange
860 860 class Foo(object):
861 861 def __init__(self):
862 862 self.foo = 1
863 863 self.bar = re.compile(r'\s+')
864 864 self.blub = dict.fromkeys(range(30), randrange(1, 40))
865 865 self.hehe = 23424.234234
866 866 self.list = ["blub", "blah", self]
867 867
868 868 def get_foo(self):
869 869 print("foo")
870 870
871 871 pprint(Foo(), verbose=True)
@@ -1,46 +1,46 b''
1 1 """Some simple tests for the plugin while running scripts.
2 2 """
3 3 # Module imports
4 4 # Std lib
5 5 import inspect
6 6
7 7 # Our own
8 8
9 9 #-----------------------------------------------------------------------------
10 10 # Testing functions
11 11
12 12 def test_trivial():
13 13 """A trivial passing test."""
14 14 pass
15 15
16 16 def doctest_run():
17 17 """Test running a trivial script.
18 18
19 19 In [13]: run simplevars.py
20 20 x is: 1
21 21 """
22 22
23 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 26 In [13]: run simplevars.py
27 27 x is: 1
28 28
29 29 In [14]: x
30 30 Out[14]: 1
31 31 """
32 32
33 33 def doctest_ivars():
34 34 """Test that variables defined interactively are picked up.
35 35 In [5]: zz=1
36 36
37 37 In [6]: zz
38 38 Out[6]: 1
39 39 """
40 40
41 41 def doctest_refs():
42 42 """DocTest reference holding issues when running scripts.
43 43
44 44 In [32]: run show_refs.py
45 45 c referrers: [<... 'dict'>]
46 46 """
General Comments 0
You need to be logged in to leave comments. Login now