##// END OF EJS Templates
Remove unused imports
Thomas Kluyver -
Show More
@@ -1,263 +1,262 b''
1 1 # encoding: utf-8
2 2 """
3 3 System command aliases.
4 4
5 5 Authors:
6 6
7 7 * Fernando Perez
8 8 * Brian Granger
9 9 """
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Copyright (C) 2008-2011 The IPython Development Team
13 13 #
14 14 # Distributed under the terms of the BSD License.
15 15 #
16 16 # The full license is in the file COPYING.txt, distributed with this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 import __builtin__
24 24 import keyword
25 25 import os
26 26 import re
27 27 import sys
28 28
29 29 from IPython.config.configurable import Configurable
30 30 from IPython.core.splitinput import split_user_input
31 31
32 32 from IPython.utils.traitlets import List, Instance
33 from IPython.utils.autoattr import auto_attr
34 33 from IPython.utils.warn import warn, error
35 34
36 35 #-----------------------------------------------------------------------------
37 36 # Utilities
38 37 #-----------------------------------------------------------------------------
39 38
40 39 # This is used as the pattern for calls to split_user_input.
41 40 shell_line_split = re.compile(r'^(\s*)()(\S+)(.*$)')
42 41
43 42 def default_aliases():
44 43 """Return list of shell aliases to auto-define.
45 44 """
46 45 # Note: the aliases defined here should be safe to use on a kernel
47 46 # regardless of what frontend it is attached to. Frontends that use a
48 47 # kernel in-process can define additional aliases that will only work in
49 48 # their case. For example, things like 'less' or 'clear' that manipulate
50 49 # the terminal should NOT be declared here, as they will only work if the
51 50 # kernel is running inside a true terminal, and not over the network.
52 51
53 52 if os.name == 'posix':
54 53 default_aliases = [('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
55 54 ('mv', 'mv -i'), ('rm', 'rm -i'), ('cp', 'cp -i'),
56 55 ('cat', 'cat'),
57 56 ]
58 57 # Useful set of ls aliases. The GNU and BSD options are a little
59 58 # different, so we make aliases that provide as similar as possible
60 59 # behavior in ipython, by passing the right flags for each platform
61 60 if sys.platform.startswith('linux'):
62 61 ls_aliases = [('ls', 'ls -F --color'),
63 62 # long ls
64 63 ('ll', 'ls -F -o --color'),
65 64 # ls normal files only
66 65 ('lf', 'ls -F -o --color %l | grep ^-'),
67 66 # ls symbolic links
68 67 ('lk', 'ls -F -o --color %l | grep ^l'),
69 68 # directories or links to directories,
70 69 ('ldir', 'ls -F -o --color %l | grep /$'),
71 70 # things which are executable
72 71 ('lx', 'ls -F -o --color %l | grep ^-..x'),
73 72 ]
74 73 else:
75 74 # BSD, OSX, etc.
76 75 ls_aliases = [('ls', 'ls -F'),
77 76 # long ls
78 77 ('ll', 'ls -F -l'),
79 78 # ls normal files only
80 79 ('lf', 'ls -F -l %l | grep ^-'),
81 80 # ls symbolic links
82 81 ('lk', 'ls -F -l %l | grep ^l'),
83 82 # directories or links to directories,
84 83 ('ldir', 'ls -F -l %l | grep /$'),
85 84 # things which are executable
86 85 ('lx', 'ls -F -l %l | grep ^-..x'),
87 86 ]
88 87 default_aliases = default_aliases + ls_aliases
89 88 elif os.name in ['nt', 'dos']:
90 89 default_aliases = [('ls', 'dir /on'),
91 90 ('ddir', 'dir /ad /on'), ('ldir', 'dir /ad /on'),
92 91 ('mkdir', 'mkdir'), ('rmdir', 'rmdir'),
93 92 ('echo', 'echo'), ('ren', 'ren'), ('copy', 'copy'),
94 93 ]
95 94 else:
96 95 default_aliases = []
97 96
98 97 return default_aliases
99 98
100 99
101 100 class AliasError(Exception):
102 101 pass
103 102
104 103
105 104 class InvalidAliasError(AliasError):
106 105 pass
107 106
108 107 #-----------------------------------------------------------------------------
109 108 # Main AliasManager class
110 109 #-----------------------------------------------------------------------------
111 110
112 111 class AliasManager(Configurable):
113 112
114 113 default_aliases = List(default_aliases(), config=True)
115 114 user_aliases = List(default_value=[], config=True)
116 115 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
117 116
118 117 def __init__(self, shell=None, config=None):
119 118 super(AliasManager, self).__init__(shell=shell, config=config)
120 119 self.alias_table = {}
121 120 self.exclude_aliases()
122 121 self.init_aliases()
123 122
124 123 def __contains__(self, name):
125 124 return name in self.alias_table
126 125
127 126 @property
128 127 def aliases(self):
129 128 return [(item[0], item[1][1]) for item in self.alias_table.iteritems()]
130 129
131 130 def exclude_aliases(self):
132 131 # set of things NOT to alias (keywords, builtins and some magics)
133 132 no_alias = set(['cd','popd','pushd','dhist','alias','unalias'])
134 133 no_alias.update(set(keyword.kwlist))
135 134 no_alias.update(set(__builtin__.__dict__.keys()))
136 135 self.no_alias = no_alias
137 136
138 137 def init_aliases(self):
139 138 # Load default aliases
140 139 for name, cmd in self.default_aliases:
141 140 self.soft_define_alias(name, cmd)
142 141
143 142 # Load user aliases
144 143 for name, cmd in self.user_aliases:
145 144 self.soft_define_alias(name, cmd)
146 145
147 146 def clear_aliases(self):
148 147 self.alias_table.clear()
149 148
150 149 def soft_define_alias(self, name, cmd):
151 150 """Define an alias, but don't raise on an AliasError."""
152 151 try:
153 152 self.define_alias(name, cmd)
154 153 except AliasError as e:
155 154 error("Invalid alias: %s" % e)
156 155
157 156 def define_alias(self, name, cmd):
158 157 """Define a new alias after validating it.
159 158
160 159 This will raise an :exc:`AliasError` if there are validation
161 160 problems.
162 161 """
163 162 nargs = self.validate_alias(name, cmd)
164 163 self.alias_table[name] = (nargs, cmd)
165 164
166 165 def undefine_alias(self, name):
167 166 if name in self.alias_table:
168 167 del self.alias_table[name]
169 168
170 169 def validate_alias(self, name, cmd):
171 170 """Validate an alias and return the its number of arguments."""
172 171 if name in self.no_alias:
173 172 raise InvalidAliasError("The name %s can't be aliased "
174 173 "because it is a keyword or builtin." % name)
175 174 if not (isinstance(cmd, basestring)):
176 175 raise InvalidAliasError("An alias command must be a string, "
177 176 "got: %r" % cmd)
178 177 nargs = cmd.count('%s')
179 178 if nargs>0 and cmd.find('%l')>=0:
180 179 raise InvalidAliasError('The %s and %l specifiers are mutually '
181 180 'exclusive in alias definitions.')
182 181 return nargs
183 182
184 183 def call_alias(self, alias, rest=''):
185 184 """Call an alias given its name and the rest of the line."""
186 185 cmd = self.transform_alias(alias, rest)
187 186 try:
188 187 self.shell.system(cmd)
189 188 except:
190 189 self.shell.showtraceback()
191 190
192 191 def transform_alias(self, alias,rest=''):
193 192 """Transform alias to system command string."""
194 193 nargs, cmd = self.alias_table[alias]
195 194
196 195 if ' ' in cmd and os.path.isfile(cmd):
197 196 cmd = '"%s"' % cmd
198 197
199 198 # Expand the %l special to be the user's input line
200 199 if cmd.find('%l') >= 0:
201 200 cmd = cmd.replace('%l', rest)
202 201 rest = ''
203 202 if nargs==0:
204 203 # Simple, argument-less aliases
205 204 cmd = '%s %s' % (cmd, rest)
206 205 else:
207 206 # Handle aliases with positional arguments
208 207 args = rest.split(None, nargs)
209 208 if len(args) < nargs:
210 209 raise AliasError('Alias <%s> requires %s arguments, %s given.' %
211 210 (alias, nargs, len(args)))
212 211 cmd = '%s %s' % (cmd % tuple(args[:nargs]),' '.join(args[nargs:]))
213 212 return cmd
214 213
215 214 def expand_alias(self, line):
216 215 """ Expand an alias in the command line
217 216
218 217 Returns the provided command line, possibly with the first word
219 218 (command) translated according to alias expansion rules.
220 219
221 220 [ipython]|16> _ip.expand_aliases("np myfile.txt")
222 221 <16> 'q:/opt/np/notepad++.exe myfile.txt'
223 222 """
224 223
225 224 pre,_,fn,rest = split_user_input(line)
226 225 res = pre + self.expand_aliases(fn, rest)
227 226 return res
228 227
229 228 def expand_aliases(self, fn, rest):
230 229 """Expand multiple levels of aliases:
231 230
232 231 if:
233 232
234 233 alias foo bar /tmp
235 234 alias baz foo
236 235
237 236 then:
238 237
239 238 baz huhhahhei -> bar /tmp huhhahhei
240 239 """
241 240 line = fn + " " + rest
242 241
243 242 done = set()
244 243 while 1:
245 244 pre,_,fn,rest = split_user_input(line, shell_line_split)
246 245 if fn in self.alias_table:
247 246 if fn in done:
248 247 warn("Cyclic alias definition, repeated '%s'" % fn)
249 248 return ""
250 249 done.add(fn)
251 250
252 251 l2 = self.transform_alias(fn, rest)
253 252 if l2 == line:
254 253 break
255 254 # ls -> ls -F should not recurse forever
256 255 if l2.split(None,1)[0] == line.split(None,1)[0]:
257 256 line = l2
258 257 break
259 258 line=l2
260 259 else:
261 260 break
262 261
263 262 return line
@@ -1,933 +1,932 b''
1 1 """Word completion for IPython.
2 2
3 3 This module is a fork of the rlcompleter module in the Python standard
4 4 library. The original enhancements made to rlcompleter have been sent
5 5 upstream and were accepted as of Python 2.3, but we need a lot more
6 6 functionality specific to IPython, so this module will continue to live as an
7 7 IPython-specific utility.
8 8
9 9 Original rlcompleter documentation:
10 10
11 11 This requires the latest extension to the readline module (the
12 12 completes keywords, built-ins and globals in __main__; when completing
13 13 NAME.NAME..., it evaluates (!) the expression up to the last dot and
14 14 completes its attributes.
15 15
16 16 It's very cool to do "import string" type "string.", hit the
17 17 completion key (twice), and see the list of names defined by the
18 18 string module!
19 19
20 20 Tip: to use the tab key as the completion key, call
21 21
22 22 readline.parse_and_bind("tab: complete")
23 23
24 24 Notes:
25 25
26 26 - Exceptions raised by the completer function are *ignored* (and
27 27 generally cause the completion to fail). This is a feature -- since
28 28 readline sets the tty device in raw (or cbreak) mode, printing a
29 29 traceback wouldn't work well without some complicated hoopla to save,
30 30 reset and restore the tty state.
31 31
32 32 - The evaluation of the NAME.NAME... form may cause arbitrary
33 33 application defined code to be executed if an object with a
34 34 __getattr__ hook is found. Since it is the responsibility of the
35 35 application (or the user) to enable this feature, I consider this an
36 36 acceptable risk. More complicated expressions (e.g. function calls or
37 37 indexing operations) are *not* evaluated.
38 38
39 39 - GNU readline is also used by the built-in functions input() and
40 40 raw_input(), and thus these also benefit/suffer from the completer
41 41 features. Clearly an interactive application can benefit by
42 42 specifying its own completer function and using raw_input() for all
43 43 its input.
44 44
45 45 - When the original stdin is not a tty device, GNU readline is never
46 46 used, and this module (and the readline module) are silently inactive.
47 47 """
48 48
49 49 #*****************************************************************************
50 50 #
51 51 # Since this file is essentially a minimally modified copy of the rlcompleter
52 52 # module which is part of the standard Python distribution, I assume that the
53 53 # proper procedure is to maintain its copyright as belonging to the Python
54 54 # Software Foundation (in addition to my own, for all new code).
55 55 #
56 56 # Copyright (C) 2008 IPython Development Team
57 57 # Copyright (C) 2001 Fernando Perez. <fperez@colorado.edu>
58 58 # Copyright (C) 2001 Python Software Foundation, www.python.org
59 59 #
60 60 # Distributed under the terms of the BSD License. The full license is in
61 61 # the file COPYING, distributed as part of this software.
62 62 #
63 63 #*****************************************************************************
64 64
65 65 #-----------------------------------------------------------------------------
66 66 # Imports
67 67 #-----------------------------------------------------------------------------
68 68
69 69 import __builtin__
70 70 import __main__
71 71 import glob
72 72 import inspect
73 73 import itertools
74 74 import keyword
75 75 import os
76 76 import re
77 import shlex
78 77 import sys
79 78
80 79 from IPython.config.configurable import Configurable
81 80 from IPython.core.error import TryNext
82 81 from IPython.core.inputsplitter import ESC_MAGIC
83 82 from IPython.utils import generics
84 83 from IPython.utils import io
85 84 from IPython.utils.dir2 import dir2
86 85 from IPython.utils.process import arg_split
87 86 from IPython.utils.traitlets import CBool, Enum
88 87
89 88 #-----------------------------------------------------------------------------
90 89 # Globals
91 90 #-----------------------------------------------------------------------------
92 91
93 92 # Public API
94 93 __all__ = ['Completer','IPCompleter']
95 94
96 95 if sys.platform == 'win32':
97 96 PROTECTABLES = ' '
98 97 else:
99 98 PROTECTABLES = ' ()[]{}?=\\|;:\'#*"^&'
100 99
101 100 #-----------------------------------------------------------------------------
102 101 # Main functions and classes
103 102 #-----------------------------------------------------------------------------
104 103
105 104 def has_open_quotes(s):
106 105 """Return whether a string has open quotes.
107 106
108 107 This simply counts whether the number of quote characters of either type in
109 108 the string is odd.
110 109
111 110 Returns
112 111 -------
113 112 If there is an open quote, the quote character is returned. Else, return
114 113 False.
115 114 """
116 115 # We check " first, then ', so complex cases with nested quotes will get
117 116 # the " to take precedence.
118 117 if s.count('"') % 2:
119 118 return '"'
120 119 elif s.count("'") % 2:
121 120 return "'"
122 121 else:
123 122 return False
124 123
125 124
126 125 def protect_filename(s):
127 126 """Escape a string to protect certain characters."""
128 127
129 128 return "".join([(ch in PROTECTABLES and '\\' + ch or ch)
130 129 for ch in s])
131 130
132 131 def expand_user(path):
133 132 """Expand '~'-style usernames in strings.
134 133
135 134 This is similar to :func:`os.path.expanduser`, but it computes and returns
136 135 extra information that will be useful if the input was being used in
137 136 computing completions, and you wish to return the completions with the
138 137 original '~' instead of its expanded value.
139 138
140 139 Parameters
141 140 ----------
142 141 path : str
143 142 String to be expanded. If no ~ is present, the output is the same as the
144 143 input.
145 144
146 145 Returns
147 146 -------
148 147 newpath : str
149 148 Result of ~ expansion in the input path.
150 149 tilde_expand : bool
151 150 Whether any expansion was performed or not.
152 151 tilde_val : str
153 152 The value that ~ was replaced with.
154 153 """
155 154 # Default values
156 155 tilde_expand = False
157 156 tilde_val = ''
158 157 newpath = path
159 158
160 159 if path.startswith('~'):
161 160 tilde_expand = True
162 161 rest = len(path)-1
163 162 newpath = os.path.expanduser(path)
164 163 if rest:
165 164 tilde_val = newpath[:-rest]
166 165 else:
167 166 tilde_val = newpath
168 167
169 168 return newpath, tilde_expand, tilde_val
170 169
171 170
172 171 def compress_user(path, tilde_expand, tilde_val):
173 172 """Does the opposite of expand_user, with its outputs.
174 173 """
175 174 if tilde_expand:
176 175 return path.replace(tilde_val, '~')
177 176 else:
178 177 return path
179 178
180 179
181 180 class Bunch(object): pass
182 181
183 182
184 183 DELIMS = ' \t\n`!@#$^&*()=+[{]}\\|;:\'",<>?'
185 184 GREEDY_DELIMS = ' =\r\n'
186 185
187 186
188 187 class CompletionSplitter(object):
189 188 """An object to split an input line in a manner similar to readline.
190 189
191 190 By having our own implementation, we can expose readline-like completion in
192 191 a uniform manner to all frontends. This object only needs to be given the
193 192 line of text to be split and the cursor position on said line, and it
194 193 returns the 'word' to be completed on at the cursor after splitting the
195 194 entire line.
196 195
197 196 What characters are used as splitting delimiters can be controlled by
198 197 setting the `delims` attribute (this is a property that internally
199 198 automatically builds the necessary regular expression)"""
200 199
201 200 # Private interface
202 201
203 202 # A string of delimiter characters. The default value makes sense for
204 203 # IPython's most typical usage patterns.
205 204 _delims = DELIMS
206 205
207 206 # The expression (a normal string) to be compiled into a regular expression
208 207 # for actual splitting. We store it as an attribute mostly for ease of
209 208 # debugging, since this type of code can be so tricky to debug.
210 209 _delim_expr = None
211 210
212 211 # The regular expression that does the actual splitting
213 212 _delim_re = None
214 213
215 214 def __init__(self, delims=None):
216 215 delims = CompletionSplitter._delims if delims is None else delims
217 216 self.delims = delims
218 217
219 218 @property
220 219 def delims(self):
221 220 """Return the string of delimiter characters."""
222 221 return self._delims
223 222
224 223 @delims.setter
225 224 def delims(self, delims):
226 225 """Set the delimiters for line splitting."""
227 226 expr = '[' + ''.join('\\'+ c for c in delims) + ']'
228 227 self._delim_re = re.compile(expr)
229 228 self._delims = delims
230 229 self._delim_expr = expr
231 230
232 231 def split_line(self, line, cursor_pos=None):
233 232 """Split a line of text with a cursor at the given position.
234 233 """
235 234 l = line if cursor_pos is None else line[:cursor_pos]
236 235 return self._delim_re.split(l)[-1]
237 236
238 237
239 238 class Completer(Configurable):
240 239
241 240 greedy = CBool(False, config=True,
242 241 help="""Activate greedy completion
243 242
244 243 This will enable completion on elements of lists, results of function calls, etc.,
245 244 but can be unsafe because the code is actually evaluated on TAB.
246 245 """
247 246 )
248 247
249 248
250 249 def __init__(self, namespace=None, global_namespace=None, config=None, **kwargs):
251 250 """Create a new completer for the command line.
252 251
253 252 Completer(namespace=ns,global_namespace=ns2) -> completer instance.
254 253
255 254 If unspecified, the default namespace where completions are performed
256 255 is __main__ (technically, __main__.__dict__). Namespaces should be
257 256 given as dictionaries.
258 257
259 258 An optional second namespace can be given. This allows the completer
260 259 to handle cases where both the local and global scopes need to be
261 260 distinguished.
262 261
263 262 Completer instances should be used as the completion mechanism of
264 263 readline via the set_completer() call:
265 264
266 265 readline.set_completer(Completer(my_namespace).complete)
267 266 """
268 267
269 268 # Don't bind to namespace quite yet, but flag whether the user wants a
270 269 # specific namespace or to use __main__.__dict__. This will allow us
271 270 # to bind to __main__.__dict__ at completion time, not now.
272 271 if namespace is None:
273 272 self.use_main_ns = 1
274 273 else:
275 274 self.use_main_ns = 0
276 275 self.namespace = namespace
277 276
278 277 # The global namespace, if given, can be bound directly
279 278 if global_namespace is None:
280 279 self.global_namespace = {}
281 280 else:
282 281 self.global_namespace = global_namespace
283 282
284 283 super(Completer, self).__init__(config=config, **kwargs)
285 284
286 285 def complete(self, text, state):
287 286 """Return the next possible completion for 'text'.
288 287
289 288 This is called successively with state == 0, 1, 2, ... until it
290 289 returns None. The completion should begin with 'text'.
291 290
292 291 """
293 292 if self.use_main_ns:
294 293 self.namespace = __main__.__dict__
295 294
296 295 if state == 0:
297 296 if "." in text:
298 297 self.matches = self.attr_matches(text)
299 298 else:
300 299 self.matches = self.global_matches(text)
301 300 try:
302 301 return self.matches[state]
303 302 except IndexError:
304 303 return None
305 304
306 305 def global_matches(self, text):
307 306 """Compute matches when text is a simple name.
308 307
309 308 Return a list of all keywords, built-in functions and names currently
310 309 defined in self.namespace or self.global_namespace that match.
311 310
312 311 """
313 312 #print 'Completer->global_matches, txt=%r' % text # dbg
314 313 matches = []
315 314 match_append = matches.append
316 315 n = len(text)
317 316 for lst in [keyword.kwlist,
318 317 __builtin__.__dict__.keys(),
319 318 self.namespace.keys(),
320 319 self.global_namespace.keys()]:
321 320 for word in lst:
322 321 if word[:n] == text and word != "__builtins__":
323 322 match_append(word)
324 323 return matches
325 324
326 325 def attr_matches(self, text):
327 326 """Compute matches when text contains a dot.
328 327
329 328 Assuming the text is of the form NAME.NAME....[NAME], and is
330 329 evaluatable in self.namespace or self.global_namespace, it will be
331 330 evaluated and its attributes (as revealed by dir()) are used as
332 331 possible completions. (For class instances, class members are are
333 332 also considered.)
334 333
335 334 WARNING: this can still invoke arbitrary C code, if an object
336 335 with a __getattr__ hook is evaluated.
337 336
338 337 """
339 338
340 339 #io.rprint('Completer->attr_matches, txt=%r' % text) # dbg
341 340 # Another option, seems to work great. Catches things like ''.<tab>
342 341 m = re.match(r"(\S+(\.\w+)*)\.(\w*)$", text)
343 342
344 343 if m:
345 344 expr, attr = m.group(1, 3)
346 345 elif self.greedy:
347 346 m2 = re.match(r"(.+)\.(\w*)$", self.line_buffer)
348 347 if not m2:
349 348 return []
350 349 expr, attr = m2.group(1,2)
351 350 else:
352 351 return []
353 352
354 353 try:
355 354 obj = eval(expr, self.namespace)
356 355 except:
357 356 try:
358 357 obj = eval(expr, self.global_namespace)
359 358 except:
360 359 return []
361 360
362 361 if self.limit_to__all__ and hasattr(obj, '__all__'):
363 362 words = get__all__entries(obj)
364 363 else:
365 364 words = dir2(obj)
366 365
367 366 try:
368 367 words = generics.complete_object(obj, words)
369 368 except TryNext:
370 369 pass
371 370 except Exception:
372 371 # Silence errors from completion function
373 372 #raise # dbg
374 373 pass
375 374 # Build match list to return
376 375 n = len(attr)
377 376 res = ["%s.%s" % (expr, w) for w in words if w[:n] == attr ]
378 377 return res
379 378
380 379
381 380 def get__all__entries(obj):
382 381 """returns the strings in the __all__ attribute"""
383 382 try:
384 383 words = getattr(obj, '__all__')
385 384 except:
386 385 return []
387 386
388 387 return [w for w in words if isinstance(w, basestring)]
389 388
390 389
391 390 class IPCompleter(Completer):
392 391 """Extension of the completer class with IPython-specific features"""
393 392
394 393 def _greedy_changed(self, name, old, new):
395 394 """update the splitter and readline delims when greedy is changed"""
396 395 if new:
397 396 self.splitter.delims = GREEDY_DELIMS
398 397 else:
399 398 self.splitter.delims = DELIMS
400 399
401 400 if self.readline:
402 401 self.readline.set_completer_delims(self.splitter.delims)
403 402
404 403 merge_completions = CBool(True, config=True,
405 404 help="""Whether to merge completion results into a single list
406 405
407 406 If False, only the completion results from the first non-empty
408 407 completer will be returned.
409 408 """
410 409 )
411 410 omit__names = Enum((0,1,2), default_value=2, config=True,
412 411 help="""Instruct the completer to omit private method names
413 412
414 413 Specifically, when completing on ``object.<tab>``.
415 414
416 415 When 2 [default]: all names that start with '_' will be excluded.
417 416
418 417 When 1: all 'magic' names (``__foo__``) will be excluded.
419 418
420 419 When 0: nothing will be excluded.
421 420 """
422 421 )
423 422 limit_to__all__ = CBool(default_value=False, config=True,
424 423 help="""Instruct the completer to use __all__ for the completion
425 424
426 425 Specifically, when completing on ``object.<tab>``.
427 426
428 427 When True: only those names in obj.__all__ will be included.
429 428
430 429 When False [default]: the __all__ attribute is ignored
431 430 """
432 431 )
433 432
434 433 def __init__(self, shell=None, namespace=None, global_namespace=None,
435 434 alias_table=None, use_readline=True,
436 435 config=None, **kwargs):
437 436 """IPCompleter() -> completer
438 437
439 438 Return a completer object suitable for use by the readline library
440 439 via readline.set_completer().
441 440
442 441 Inputs:
443 442
444 443 - shell: a pointer to the ipython shell itself. This is needed
445 444 because this completer knows about magic functions, and those can
446 445 only be accessed via the ipython instance.
447 446
448 447 - namespace: an optional dict where completions are performed.
449 448
450 449 - global_namespace: secondary optional dict for completions, to
451 450 handle cases (such as IPython embedded inside functions) where
452 451 both Python scopes are visible.
453 452
454 453 - If alias_table is supplied, it should be a dictionary of aliases
455 454 to complete.
456 455
457 456 use_readline : bool, optional
458 457 If true, use the readline library. This completer can still function
459 458 without readline, though in that case callers must provide some extra
460 459 information on each call about the current line."""
461 460
462 461 self.magic_escape = ESC_MAGIC
463 462 self.splitter = CompletionSplitter()
464 463
465 464 # Readline configuration, only used by the rlcompleter method.
466 465 if use_readline:
467 466 # We store the right version of readline so that later code
468 467 import IPython.utils.rlineimpl as readline
469 468 self.readline = readline
470 469 else:
471 470 self.readline = None
472 471
473 472 # _greedy_changed() depends on splitter and readline being defined:
474 473 Completer.__init__(self, namespace=namespace, global_namespace=global_namespace,
475 474 config=config, **kwargs)
476 475
477 476 # List where completion matches will be stored
478 477 self.matches = []
479 478 self.shell = shell
480 479 if alias_table is None:
481 480 alias_table = {}
482 481 self.alias_table = alias_table
483 482 # Regexp to split filenames with spaces in them
484 483 self.space_name_re = re.compile(r'([^\\] )')
485 484 # Hold a local ref. to glob.glob for speed
486 485 self.glob = glob.glob
487 486
488 487 # Determine if we are running on 'dumb' terminals, like (X)Emacs
489 488 # buffers, to avoid completion problems.
490 489 term = os.environ.get('TERM','xterm')
491 490 self.dumb_terminal = term in ['dumb','emacs']
492 491
493 492 # Special handling of backslashes needed in win32 platforms
494 493 if sys.platform == "win32":
495 494 self.clean_glob = self._clean_glob_win32
496 495 else:
497 496 self.clean_glob = self._clean_glob
498 497
499 498 # All active matcher routines for completion
500 499 self.matchers = [self.python_matches,
501 500 self.file_matches,
502 501 self.magic_matches,
503 502 self.alias_matches,
504 503 self.python_func_kw_matches,
505 504 ]
506 505
507 506 def all_completions(self, text):
508 507 """
509 508 Wrapper around the complete method for the benefit of emacs
510 509 and pydb.
511 510 """
512 511 return self.complete(text)[1]
513 512
514 513 def _clean_glob(self,text):
515 514 return self.glob("%s*" % text)
516 515
517 516 def _clean_glob_win32(self,text):
518 517 return [f.replace("\\","/")
519 518 for f in self.glob("%s*" % text)]
520 519
521 520 def file_matches(self, text):
522 521 """Match filenames, expanding ~USER type strings.
523 522
524 523 Most of the seemingly convoluted logic in this completer is an
525 524 attempt to handle filenames with spaces in them. And yet it's not
526 525 quite perfect, because Python's readline doesn't expose all of the
527 526 GNU readline details needed for this to be done correctly.
528 527
529 528 For a filename with a space in it, the printed completions will be
530 529 only the parts after what's already been typed (instead of the
531 530 full completions, as is normally done). I don't think with the
532 531 current (as of Python 2.3) Python readline it's possible to do
533 532 better."""
534 533
535 534 #io.rprint('Completer->file_matches: <%r>' % text) # dbg
536 535
537 536 # chars that require escaping with backslash - i.e. chars
538 537 # that readline treats incorrectly as delimiters, but we
539 538 # don't want to treat as delimiters in filename matching
540 539 # when escaped with backslash
541 540 if text.startswith('!'):
542 541 text = text[1:]
543 542 text_prefix = '!'
544 543 else:
545 544 text_prefix = ''
546 545
547 546 text_until_cursor = self.text_until_cursor
548 547 # track strings with open quotes
549 548 open_quotes = has_open_quotes(text_until_cursor)
550 549
551 550 if '(' in text_until_cursor or '[' in text_until_cursor:
552 551 lsplit = text
553 552 else:
554 553 try:
555 554 # arg_split ~ shlex.split, but with unicode bugs fixed by us
556 555 lsplit = arg_split(text_until_cursor)[-1]
557 556 except ValueError:
558 557 # typically an unmatched ", or backslash without escaped char.
559 558 if open_quotes:
560 559 lsplit = text_until_cursor.split(open_quotes)[-1]
561 560 else:
562 561 return []
563 562 except IndexError:
564 563 # tab pressed on empty line
565 564 lsplit = ""
566 565
567 566 if not open_quotes and lsplit != protect_filename(lsplit):
568 567 # if protectables are found, do matching on the whole escaped name
569 568 has_protectables = True
570 569 text0,text = text,lsplit
571 570 else:
572 571 has_protectables = False
573 572 text = os.path.expanduser(text)
574 573
575 574 if text == "":
576 575 return [text_prefix + protect_filename(f) for f in self.glob("*")]
577 576
578 577 # Compute the matches from the filesystem
579 578 m0 = self.clean_glob(text.replace('\\',''))
580 579
581 580 if has_protectables:
582 581 # If we had protectables, we need to revert our changes to the
583 582 # beginning of filename so that we don't double-write the part
584 583 # of the filename we have so far
585 584 len_lsplit = len(lsplit)
586 585 matches = [text_prefix + text0 +
587 586 protect_filename(f[len_lsplit:]) for f in m0]
588 587 else:
589 588 if open_quotes:
590 589 # if we have a string with an open quote, we don't need to
591 590 # protect the names at all (and we _shouldn't_, as it
592 591 # would cause bugs when the filesystem call is made).
593 592 matches = m0
594 593 else:
595 594 matches = [text_prefix +
596 595 protect_filename(f) for f in m0]
597 596
598 597 #io.rprint('mm', matches) # dbg
599 598
600 599 # Mark directories in input list by appending '/' to their names.
601 600 matches = [x+'/' if os.path.isdir(x) else x for x in matches]
602 601 return matches
603 602
604 603 def magic_matches(self, text):
605 604 """Match magics"""
606 605 #print 'Completer->magic_matches:',text,'lb',self.text_until_cursor # dbg
607 606 # Get all shell magics now rather than statically, so magics loaded at
608 607 # runtime show up too.
609 608 lsm = self.shell.magics_manager.lsmagic()
610 609 line_magics = lsm['line']
611 610 cell_magics = lsm['cell']
612 611 pre = self.magic_escape
613 612 pre2 = pre+pre
614 613
615 614 # Completion logic:
616 615 # - user gives %%: only do cell magics
617 616 # - user gives %: do both line and cell magics
618 617 # - no prefix: do both
619 618 # In other words, line magics are skipped if the user gives %% explicitly
620 619 bare_text = text.lstrip(pre)
621 620 comp = [ pre2+m for m in cell_magics if m.startswith(bare_text)]
622 621 if not text.startswith(pre2):
623 622 comp += [ pre+m for m in line_magics if m.startswith(bare_text)]
624 623 return comp
625 624
626 625 def alias_matches(self, text):
627 626 """Match internal system aliases"""
628 627 #print 'Completer->alias_matches:',text,'lb',self.text_until_cursor # dbg
629 628
630 629 # if we are not in the first 'item', alias matching
631 630 # doesn't make sense - unless we are starting with 'sudo' command.
632 631 main_text = self.text_until_cursor.lstrip()
633 632 if ' ' in main_text and not main_text.startswith('sudo'):
634 633 return []
635 634 text = os.path.expanduser(text)
636 635 aliases = self.alias_table.keys()
637 636 if text == '':
638 637 return aliases
639 638 else:
640 639 return [a for a in aliases if a.startswith(text)]
641 640
642 641 def python_matches(self,text):
643 642 """Match attributes or global python names"""
644 643
645 644 #io.rprint('Completer->python_matches, txt=%r' % text) # dbg
646 645 if "." in text:
647 646 try:
648 647 matches = self.attr_matches(text)
649 648 if text.endswith('.') and self.omit__names:
650 649 if self.omit__names == 1:
651 650 # true if txt is _not_ a __ name, false otherwise:
652 651 no__name = (lambda txt:
653 652 re.match(r'.*\.__.*?__',txt) is None)
654 653 else:
655 654 # true if txt is _not_ a _ name, false otherwise:
656 655 no__name = (lambda txt:
657 656 re.match(r'.*\._.*?',txt) is None)
658 657 matches = filter(no__name, matches)
659 658 except NameError:
660 659 # catches <undefined attributes>.<tab>
661 660 matches = []
662 661 else:
663 662 matches = self.global_matches(text)
664 663
665 664 return matches
666 665
667 666 def _default_arguments(self, obj):
668 667 """Return the list of default arguments of obj if it is callable,
669 668 or empty list otherwise."""
670 669
671 670 if not (inspect.isfunction(obj) or inspect.ismethod(obj)):
672 671 # for classes, check for __init__,__new__
673 672 if inspect.isclass(obj):
674 673 obj = (getattr(obj,'__init__',None) or
675 674 getattr(obj,'__new__',None))
676 675 # for all others, check if they are __call__able
677 676 elif hasattr(obj, '__call__'):
678 677 obj = obj.__call__
679 678 # XXX: is there a way to handle the builtins ?
680 679 try:
681 680 args,_,_1,defaults = inspect.getargspec(obj)
682 681 if defaults:
683 682 return args[-len(defaults):]
684 683 except TypeError: pass
685 684 return []
686 685
687 686 def python_func_kw_matches(self,text):
688 687 """Match named parameters (kwargs) of the last open function"""
689 688
690 689 if "." in text: # a parameter cannot be dotted
691 690 return []
692 691 try: regexp = self.__funcParamsRegex
693 692 except AttributeError:
694 693 regexp = self.__funcParamsRegex = re.compile(r'''
695 694 '.*?(?<!\\)' | # single quoted strings or
696 695 ".*?(?<!\\)" | # double quoted strings or
697 696 \w+ | # identifier
698 697 \S # other characters
699 698 ''', re.VERBOSE | re.DOTALL)
700 699 # 1. find the nearest identifier that comes before an unclosed
701 700 # parenthesis before the cursor
702 701 # e.g. for "foo (1+bar(x), pa<cursor>,a=1)", the candidate is "foo"
703 702 tokens = regexp.findall(self.text_until_cursor)
704 703 tokens.reverse()
705 704 iterTokens = iter(tokens); openPar = 0
706 705 for token in iterTokens:
707 706 if token == ')':
708 707 openPar -= 1
709 708 elif token == '(':
710 709 openPar += 1
711 710 if openPar > 0:
712 711 # found the last unclosed parenthesis
713 712 break
714 713 else:
715 714 return []
716 715 # 2. Concatenate dotted names ("foo.bar" for "foo.bar(x, pa" )
717 716 ids = []
718 717 isId = re.compile(r'\w+$').match
719 718 while True:
720 719 try:
721 720 ids.append(next(iterTokens))
722 721 if not isId(ids[-1]):
723 722 ids.pop(); break
724 723 if not next(iterTokens) == '.':
725 724 break
726 725 except StopIteration:
727 726 break
728 727 # lookup the candidate callable matches either using global_matches
729 728 # or attr_matches for dotted names
730 729 if len(ids) == 1:
731 730 callableMatches = self.global_matches(ids[0])
732 731 else:
733 732 callableMatches = self.attr_matches('.'.join(ids[::-1]))
734 733 argMatches = []
735 734 for callableMatch in callableMatches:
736 735 try:
737 736 namedArgs = self._default_arguments(eval(callableMatch,
738 737 self.namespace))
739 738 except:
740 739 continue
741 740 for namedArg in namedArgs:
742 741 if namedArg.startswith(text):
743 742 argMatches.append("%s=" %namedArg)
744 743 return argMatches
745 744
746 745 def dispatch_custom_completer(self, text):
747 746 #io.rprint("Custom! '%s' %s" % (text, self.custom_completers)) # dbg
748 747 line = self.line_buffer
749 748 if not line.strip():
750 749 return None
751 750
752 751 # Create a little structure to pass all the relevant information about
753 752 # the current completion to any custom completer.
754 753 event = Bunch()
755 754 event.line = line
756 755 event.symbol = text
757 756 cmd = line.split(None,1)[0]
758 757 event.command = cmd
759 758 event.text_until_cursor = self.text_until_cursor
760 759
761 760 #print "\ncustom:{%s]\n" % event # dbg
762 761
763 762 # for foo etc, try also to find completer for %foo
764 763 if not cmd.startswith(self.magic_escape):
765 764 try_magic = self.custom_completers.s_matches(
766 765 self.magic_escape + cmd)
767 766 else:
768 767 try_magic = []
769 768
770 769 for c in itertools.chain(self.custom_completers.s_matches(cmd),
771 770 try_magic,
772 771 self.custom_completers.flat_matches(self.text_until_cursor)):
773 772 #print "try",c # dbg
774 773 try:
775 774 res = c(event)
776 775 if res:
777 776 # first, try case sensitive match
778 777 withcase = [r for r in res if r.startswith(text)]
779 778 if withcase:
780 779 return withcase
781 780 # if none, then case insensitive ones are ok too
782 781 text_low = text.lower()
783 782 return [r for r in res if r.lower().startswith(text_low)]
784 783 except TryNext:
785 784 pass
786 785
787 786 return None
788 787
789 788 def complete(self, text=None, line_buffer=None, cursor_pos=None):
790 789 """Find completions for the given text and line context.
791 790
792 791 This is called successively with state == 0, 1, 2, ... until it
793 792 returns None. The completion should begin with 'text'.
794 793
795 794 Note that both the text and the line_buffer are optional, but at least
796 795 one of them must be given.
797 796
798 797 Parameters
799 798 ----------
800 799 text : string, optional
801 800 Text to perform the completion on. If not given, the line buffer
802 801 is split using the instance's CompletionSplitter object.
803 802
804 803 line_buffer : string, optional
805 804 If not given, the completer attempts to obtain the current line
806 805 buffer via readline. This keyword allows clients which are
807 806 requesting for text completions in non-readline contexts to inform
808 807 the completer of the entire text.
809 808
810 809 cursor_pos : int, optional
811 810 Index of the cursor in the full line buffer. Should be provided by
812 811 remote frontends where kernel has no access to frontend state.
813 812
814 813 Returns
815 814 -------
816 815 text : str
817 816 Text that was actually used in the completion.
818 817
819 818 matches : list
820 819 A list of completion matches.
821 820 """
822 821 #io.rprint('\nCOMP1 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
823 822
824 823 # if the cursor position isn't given, the only sane assumption we can
825 824 # make is that it's at the end of the line (the common case)
826 825 if cursor_pos is None:
827 826 cursor_pos = len(line_buffer) if text is None else len(text)
828 827
829 828 # if text is either None or an empty string, rely on the line buffer
830 829 if not text:
831 830 text = self.splitter.split_line(line_buffer, cursor_pos)
832 831
833 832 # If no line buffer is given, assume the input text is all there was
834 833 if line_buffer is None:
835 834 line_buffer = text
836 835
837 836 self.line_buffer = line_buffer
838 837 self.text_until_cursor = self.line_buffer[:cursor_pos]
839 838 #io.rprint('COMP2 %r %r %r' % (text, line_buffer, cursor_pos)) # dbg
840 839
841 840 # Start with a clean slate of completions
842 841 self.matches[:] = []
843 842 custom_res = self.dispatch_custom_completer(text)
844 843 if custom_res is not None:
845 844 # did custom completers produce something?
846 845 self.matches = custom_res
847 846 else:
848 847 # Extend the list of completions with the results of each
849 848 # matcher, so we return results to the user from all
850 849 # namespaces.
851 850 if self.merge_completions:
852 851 self.matches = []
853 852 for matcher in self.matchers:
854 853 try:
855 854 self.matches.extend(matcher(text))
856 855 except:
857 856 # Show the ugly traceback if the matcher causes an
858 857 # exception, but do NOT crash the kernel!
859 858 sys.excepthook(*sys.exc_info())
860 859 else:
861 860 for matcher in self.matchers:
862 861 self.matches = matcher(text)
863 862 if self.matches:
864 863 break
865 864 # FIXME: we should extend our api to return a dict with completions for
866 865 # different types of objects. The rlcomplete() method could then
867 866 # simply collapse the dict into a list for readline, but we'd have
868 867 # richer completion semantics in other evironments.
869 868 self.matches = sorted(set(self.matches))
870 869 #io.rprint('COMP TEXT, MATCHES: %r, %r' % (text, self.matches)) # dbg
871 870 return text, self.matches
872 871
873 872 def rlcomplete(self, text, state):
874 873 """Return the state-th possible completion for 'text'.
875 874
876 875 This is called successively with state == 0, 1, 2, ... until it
877 876 returns None. The completion should begin with 'text'.
878 877
879 878 Parameters
880 879 ----------
881 880 text : string
882 881 Text to perform the completion on.
883 882
884 883 state : int
885 884 Counter used by readline.
886 885 """
887 886 if state==0:
888 887
889 888 self.line_buffer = line_buffer = self.readline.get_line_buffer()
890 889 cursor_pos = self.readline.get_endidx()
891 890
892 891 #io.rprint("\nRLCOMPLETE: %r %r %r" %
893 892 # (text, line_buffer, cursor_pos) ) # dbg
894 893
895 894 # if there is only a tab on a line with only whitespace, instead of
896 895 # the mostly useless 'do you want to see all million completions'
897 896 # message, just do the right thing and give the user his tab!
898 897 # Incidentally, this enables pasting of tabbed text from an editor
899 898 # (as long as autoindent is off).
900 899
901 900 # It should be noted that at least pyreadline still shows file
902 901 # completions - is there a way around it?
903 902
904 903 # don't apply this on 'dumb' terminals, such as emacs buffers, so
905 904 # we don't interfere with their own tab-completion mechanism.
906 905 if not (self.dumb_terminal or line_buffer.strip()):
907 906 self.readline.insert_text('\t')
908 907 sys.stdout.flush()
909 908 return None
910 909
911 910 # Note: debugging exceptions that may occur in completion is very
912 911 # tricky, because readline unconditionally silences them. So if
913 912 # during development you suspect a bug in the completion code, turn
914 913 # this flag on temporarily by uncommenting the second form (don't
915 914 # flip the value in the first line, as the '# dbg' marker can be
916 915 # automatically detected and is used elsewhere).
917 916 DEBUG = False
918 917 #DEBUG = True # dbg
919 918 if DEBUG:
920 919 try:
921 920 self.complete(text, line_buffer, cursor_pos)
922 921 except:
923 922 import traceback; traceback.print_exc()
924 923 else:
925 924 # The normal production version is here
926 925
927 926 # This method computes the self.matches array
928 927 self.complete(text, line_buffer, cursor_pos)
929 928
930 929 try:
931 930 return self.matches[state]
932 931 except IndexError:
933 932 return None
@@ -1,333 +1,332 b''
1 1 """Implementations for various useful completers.
2 2
3 3 These are all loaded by default by IPython.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (C) 2010-2011 The IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from __future__ import print_function
17 17
18 18 # Stdlib imports
19 19 import glob
20 20 import imp
21 21 import inspect
22 22 import os
23 23 import re
24 24 import sys
25 25
26 26 # Third-party imports
27 27 from time import time
28 28 from zipimport import zipimporter
29 29
30 30 # Our own imports
31 31 from IPython.core.completer import expand_user, compress_user
32 32 from IPython.core.error import TryNext
33 from IPython.utils import py3compat
34 33 from IPython.utils._process_common import arg_split
35 34
36 35 # FIXME: this should be pulled in with the right call via the component system
37 36 from IPython.core.ipapi import get as get_ipython
38 37
39 38 #-----------------------------------------------------------------------------
40 39 # Globals and constants
41 40 #-----------------------------------------------------------------------------
42 41
43 42 # Time in seconds after which the rootmodules will be stored permanently in the
44 43 # ipython ip.db database (kept in the user's .ipython dir).
45 44 TIMEOUT_STORAGE = 2
46 45
47 46 # Time in seconds after which we give up
48 47 TIMEOUT_GIVEUP = 20
49 48
50 49 # Regular expression for the python import statement
51 50 import_re = re.compile(r'(?P<name>[a-zA-Z_][a-zA-Z0-9_]*?)'
52 51 r'(?P<package>[/\\]__init__)?'
53 52 r'(?P<suffix>%s)$' %
54 53 r'|'.join(re.escape(s[0]) for s in imp.get_suffixes()))
55 54
56 55 # RE for the ipython %run command (python + ipython scripts)
57 56 magic_run_re = re.compile(r'.*(\.ipy|\.py[w]?)$')
58 57
59 58 #-----------------------------------------------------------------------------
60 59 # Local utilities
61 60 #-----------------------------------------------------------------------------
62 61
63 62 def module_list(path):
64 63 """
65 64 Return the list containing the names of the modules available in the given
66 65 folder.
67 66 """
68 67 # sys.path has the cwd as an empty string, but isdir/listdir need it as '.'
69 68 if path == '':
70 69 path = '.'
71 70
72 71 # A few local constants to be used in loops below
73 72 pjoin = os.path.join
74 73
75 74 if os.path.isdir(path):
76 75 # Build a list of all files in the directory and all files
77 76 # in its subdirectories. For performance reasons, do not
78 77 # recurse more than one level into subdirectories.
79 78 files = []
80 79 for root, dirs, nondirs in os.walk(path):
81 80 subdir = root[len(path)+1:]
82 81 if subdir:
83 82 files.extend(pjoin(subdir, f) for f in nondirs)
84 83 dirs[:] = [] # Do not recurse into additional subdirectories.
85 84 else:
86 85 files.extend(nondirs)
87 86
88 87 else:
89 88 try:
90 89 files = list(zipimporter(path)._files.keys())
91 90 except:
92 91 files = []
93 92
94 93 # Build a list of modules which match the import_re regex.
95 94 modules = []
96 95 for f in files:
97 96 m = import_re.match(f)
98 97 if m:
99 98 modules.append(m.group('name'))
100 99 return list(set(modules))
101 100
102 101 def get_root_modules():
103 102 """
104 103 Returns a list containing the names of all the modules available in the
105 104 folders of the pythonpath.
106 105 """
107 106 ip = get_ipython()
108 107
109 108 if 'rootmodules' in ip.db:
110 109 return ip.db['rootmodules']
111 110
112 111 t = time()
113 112 store = False
114 113 modules = list(sys.builtin_module_names)
115 114 for path in sys.path:
116 115 modules += module_list(path)
117 116 if time() - t >= TIMEOUT_STORAGE and not store:
118 117 store = True
119 118 print("\nCaching the list of root modules, please wait!")
120 119 print("(This will only be done once - type '%rehashx' to "
121 120 "reset cache!)\n")
122 121 sys.stdout.flush()
123 122 if time() - t > TIMEOUT_GIVEUP:
124 123 print("This is taking too long, we give up.\n")
125 124 ip.db['rootmodules'] = []
126 125 return []
127 126
128 127 modules = set(modules)
129 128 if '__init__' in modules:
130 129 modules.remove('__init__')
131 130 modules = list(modules)
132 131 if store:
133 132 ip.db['rootmodules'] = modules
134 133 return modules
135 134
136 135
137 136 def is_importable(module, attr, only_modules):
138 137 if only_modules:
139 138 return inspect.ismodule(getattr(module, attr))
140 139 else:
141 140 return not(attr[:2] == '__' and attr[-2:] == '__')
142 141
143 142
144 143 def try_import(mod, only_modules=False):
145 144 try:
146 145 m = __import__(mod)
147 146 except:
148 147 return []
149 148 mods = mod.split('.')
150 149 for module in mods[1:]:
151 150 m = getattr(m, module)
152 151
153 152 m_is_init = hasattr(m, '__file__') and '__init__' in m.__file__
154 153
155 154 completions = []
156 155 if (not hasattr(m, '__file__')) or (not only_modules) or m_is_init:
157 156 completions.extend( [attr for attr in dir(m) if
158 157 is_importable(m, attr, only_modules)])
159 158
160 159 completions.extend(getattr(m, '__all__', []))
161 160 if m_is_init:
162 161 completions.extend(module_list(os.path.dirname(m.__file__)))
163 162 completions = set(completions)
164 163 if '__init__' in completions:
165 164 completions.remove('__init__')
166 165 return list(completions)
167 166
168 167
169 168 #-----------------------------------------------------------------------------
170 169 # Completion-related functions.
171 170 #-----------------------------------------------------------------------------
172 171
173 172 def quick_completer(cmd, completions):
174 173 """ Easily create a trivial completer for a command.
175 174
176 175 Takes either a list of completions, or all completions in string (that will
177 176 be split on whitespace).
178 177
179 178 Example::
180 179
181 180 [d:\ipython]|1> import ipy_completers
182 181 [d:\ipython]|2> ipy_completers.quick_completer('foo', ['bar','baz'])
183 182 [d:\ipython]|3> foo b<TAB>
184 183 bar baz
185 184 [d:\ipython]|3> foo ba
186 185 """
187 186
188 187 if isinstance(completions, basestring):
189 188 completions = completions.split()
190 189
191 190 def do_complete(self, event):
192 191 return completions
193 192
194 193 get_ipython().set_hook('complete_command',do_complete, str_key = cmd)
195 194
196 195 def module_completion(line):
197 196 """
198 197 Returns a list containing the completion possibilities for an import line.
199 198
200 199 The line looks like this :
201 200 'import xml.d'
202 201 'from xml.dom import'
203 202 """
204 203
205 204 words = line.split(' ')
206 205 nwords = len(words)
207 206
208 207 # from whatever <tab> -> 'import '
209 208 if nwords == 3 and words[0] == 'from':
210 209 return ['import ']
211 210
212 211 # 'from xy<tab>' or 'import xy<tab>'
213 212 if nwords < 3 and (words[0] in ['import','from']) :
214 213 if nwords == 1:
215 214 return get_root_modules()
216 215 mod = words[1].split('.')
217 216 if len(mod) < 2:
218 217 return get_root_modules()
219 218 completion_list = try_import('.'.join(mod[:-1]), True)
220 219 return ['.'.join(mod[:-1] + [el]) for el in completion_list]
221 220
222 221 # 'from xyz import abc<tab>'
223 222 if nwords >= 3 and words[0] == 'from':
224 223 mod = words[1]
225 224 return try_import(mod)
226 225
227 226 #-----------------------------------------------------------------------------
228 227 # Completers
229 228 #-----------------------------------------------------------------------------
230 229 # These all have the func(self, event) signature to be used as custom
231 230 # completers
232 231
233 232 def module_completer(self,event):
234 233 """Give completions after user has typed 'import ...' or 'from ...'"""
235 234
236 235 # This works in all versions of python. While 2.5 has
237 236 # pkgutil.walk_packages(), that particular routine is fairly dangerous,
238 237 # since it imports *EVERYTHING* on sys.path. That is: a) very slow b) full
239 238 # of possibly problematic side effects.
240 239 # This search the folders in the sys.path for available modules.
241 240
242 241 return module_completion(event.line)
243 242
244 243 # FIXME: there's a lot of logic common to the run, cd and builtin file
245 244 # completers, that is currently reimplemented in each.
246 245
247 246 def magic_run_completer(self, event):
248 247 """Complete files that end in .py or .ipy for the %run command.
249 248 """
250 249 comps = arg_split(event.line, strict=False)
251 250 relpath = (len(comps) > 1 and comps[-1] or '').strip("'\"")
252 251
253 252 #print("\nev=", event) # dbg
254 253 #print("rp=", relpath) # dbg
255 254 #print('comps=', comps) # dbg
256 255
257 256 lglob = glob.glob
258 257 isdir = os.path.isdir
259 258 relpath, tilde_expand, tilde_val = expand_user(relpath)
260 259
261 260 dirs = [f.replace('\\','/') + "/" for f in lglob(relpath+'*') if isdir(f)]
262 261
263 262 # Find if the user has already typed the first filename, after which we
264 263 # should complete on all files, since after the first one other files may
265 264 # be arguments to the input script.
266 265
267 266 if filter(magic_run_re.match, comps):
268 267 pys = [f.replace('\\','/') for f in lglob('*')]
269 268 else:
270 269 pys = [f.replace('\\','/')
271 270 for f in lglob(relpath+'*.py') + lglob(relpath+'*.ipy') +
272 271 lglob(relpath + '*.pyw')]
273 272 #print('run comp:', dirs+pys) # dbg
274 273 return [compress_user(p, tilde_expand, tilde_val) for p in dirs+pys]
275 274
276 275
277 276 def cd_completer(self, event):
278 277 """Completer function for cd, which only returns directories."""
279 278 ip = get_ipython()
280 279 relpath = event.symbol
281 280
282 281 #print(event) # dbg
283 282 if event.line.endswith('-b') or ' -b ' in event.line:
284 283 # return only bookmark completions
285 284 bkms = self.db.get('bookmarks', None)
286 285 if bkms:
287 286 return bkms.keys()
288 287 else:
289 288 return []
290 289
291 290 if event.symbol == '-':
292 291 width_dh = str(len(str(len(ip.user_ns['_dh']) + 1)))
293 292 # jump in directory history by number
294 293 fmt = '-%0' + width_dh +'d [%s]'
295 294 ents = [ fmt % (i,s) for i,s in enumerate(ip.user_ns['_dh'])]
296 295 if len(ents) > 1:
297 296 return ents
298 297 return []
299 298
300 299 if event.symbol.startswith('--'):
301 300 return ["--" + os.path.basename(d) for d in ip.user_ns['_dh']]
302 301
303 302 # Expand ~ in path and normalize directory separators.
304 303 relpath, tilde_expand, tilde_val = expand_user(relpath)
305 304 relpath = relpath.replace('\\','/')
306 305
307 306 found = []
308 307 for d in [f.replace('\\','/') + '/' for f in glob.glob(relpath+'*')
309 308 if os.path.isdir(f)]:
310 309 if ' ' in d:
311 310 # we don't want to deal with any of that, complex code
312 311 # for this is elsewhere
313 312 raise TryNext
314 313
315 314 found.append(d)
316 315
317 316 if not found:
318 317 if os.path.isdir(relpath):
319 318 return [compress_user(relpath, tilde_expand, tilde_val)]
320 319
321 320 # if no completions so far, try bookmarks
322 321 bks = self.db.get('bookmarks',{}).iterkeys()
323 322 bkmatches = [s for s in bks if s.startswith(event.symbol)]
324 323 if bkmatches:
325 324 return bkmatches
326 325
327 326 raise TryNext
328 327
329 328 return [compress_user(p, tilde_expand, tilde_val) for p in found]
330 329
331 330 def reset_completer(self, event):
332 331 "A completer for %reset magic"
333 332 return '-f -s in out array dhist'.split()
@@ -1,566 +1,566 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 Pdb debugger class.
4 4
5 5 Modified from the standard pdb.Pdb class to avoid including readline, so that
6 6 the command line completion of other programs which include this isn't
7 7 damaged.
8 8
9 9 In the future, this class will be expanded with improvements over the standard
10 10 pdb.
11 11
12 12 The code in this file is mainly lifted out of cmd.py in Python 2.2, with minor
13 13 changes. Licensing should therefore be under the standard Python terms. For
14 14 details on the PSF (Python Software Foundation) standard license, see:
15 15
16 16 http://www.python.org/2.2.3/license.html"""
17 17
18 18 #*****************************************************************************
19 19 #
20 20 # This file is licensed under the PSF license.
21 21 #
22 22 # Copyright (C) 2001 Python Software Foundation, www.python.org
23 23 # Copyright (C) 2005-2006 Fernando Perez. <fperez@colorado.edu>
24 24 #
25 25 #
26 26 #*****************************************************************************
27 27 from __future__ import print_function
28 28
29 29 import bdb
30 30 import functools
31 31 import linecache
32 32 import sys
33 33
34 34 from IPython.utils import PyColorize, ulinecache
35 35 from IPython.core import ipapi
36 from IPython.utils import coloransi, io, openpy, py3compat
36 from IPython.utils import coloransi, io, py3compat
37 37 from IPython.core.excolors import exception_colors
38 38
39 39 # See if we can use pydb.
40 40 has_pydb = False
41 41 prompt = 'ipdb> '
42 42 #We have to check this directly from sys.argv, config struct not yet available
43 43 if '--pydb' in sys.argv:
44 44 try:
45 45 import pydb
46 46 if hasattr(pydb.pydb, "runl") and pydb.version>'1.17':
47 47 # Version 1.17 is broken, and that's what ships with Ubuntu Edgy, so we
48 48 # better protect against it.
49 49 has_pydb = True
50 50 except ImportError:
51 51 print("Pydb (http://bashdb.sourceforge.net/pydb/) does not seem to be available")
52 52
53 53 if has_pydb:
54 54 from pydb import Pdb as OldPdb
55 55 #print "Using pydb for %run -d and post-mortem" #dbg
56 56 prompt = 'ipydb> '
57 57 else:
58 58 from pdb import Pdb as OldPdb
59 59
60 60 # Allow the set_trace code to operate outside of an ipython instance, even if
61 61 # it does so with some limitations. The rest of this support is implemented in
62 62 # the Tracer constructor.
63 63 def BdbQuit_excepthook(et, ev, tb, excepthook=None):
64 64 """Exception hook which handles `BdbQuit` exceptions.
65 65
66 66 All other exceptions are processed using the `excepthook`
67 67 parameter.
68 68 """
69 69 if et==bdb.BdbQuit:
70 70 print('Exiting Debugger.')
71 71 elif excepthook is not None:
72 72 excepthook(et, ev, tb)
73 73 else:
74 74 # Backwards compatibility. Raise deprecation warning?
75 75 BdbQuit_excepthook.excepthook_ori(et,ev,tb)
76 76
77 77 def BdbQuit_IPython_excepthook(self,et,ev,tb,tb_offset=None):
78 78 print('Exiting Debugger.')
79 79
80 80
81 81 class Tracer(object):
82 82 """Class for local debugging, similar to pdb.set_trace.
83 83
84 84 Instances of this class, when called, behave like pdb.set_trace, but
85 85 providing IPython's enhanced capabilities.
86 86
87 87 This is implemented as a class which must be initialized in your own code
88 88 and not as a standalone function because we need to detect at runtime
89 89 whether IPython is already active or not. That detection is done in the
90 90 constructor, ensuring that this code plays nicely with a running IPython,
91 91 while functioning acceptably (though with limitations) if outside of it.
92 92 """
93 93
94 94 def __init__(self,colors=None):
95 95 """Create a local debugger instance.
96 96
97 97 :Parameters:
98 98
99 99 - `colors` (None): a string containing the name of the color scheme to
100 100 use, it must be one of IPython's valid color schemes. If not given, the
101 101 function will default to the current IPython scheme when running inside
102 102 IPython, and to 'NoColor' otherwise.
103 103
104 104 Usage example:
105 105
106 106 from IPython.core.debugger import Tracer; debug_here = Tracer()
107 107
108 108 ... later in your code
109 109 debug_here() # -> will open up the debugger at that point.
110 110
111 111 Once the debugger activates, you can use all of its regular commands to
112 112 step through code, set breakpoints, etc. See the pdb documentation
113 113 from the Python standard library for usage details.
114 114 """
115 115
116 116 try:
117 117 ip = get_ipython()
118 118 except NameError:
119 119 # Outside of ipython, we set our own exception hook manually
120 120 sys.excepthook = functools.partial(BdbQuit_excepthook,
121 121 excepthook=sys.excepthook)
122 122 def_colors = 'NoColor'
123 123 try:
124 124 # Limited tab completion support
125 125 import readline
126 126 readline.parse_and_bind('tab: complete')
127 127 except ImportError:
128 128 pass
129 129 else:
130 130 # In ipython, we use its custom exception handler mechanism
131 131 def_colors = ip.colors
132 132 ip.set_custom_exc((bdb.BdbQuit,), BdbQuit_IPython_excepthook)
133 133
134 134 if colors is None:
135 135 colors = def_colors
136 136
137 137 # The stdlib debugger internally uses a modified repr from the `repr`
138 138 # module, that limits the length of printed strings to a hardcoded
139 139 # limit of 30 characters. That much trimming is too aggressive, let's
140 140 # at least raise that limit to 80 chars, which should be enough for
141 141 # most interactive uses.
142 142 try:
143 143 from repr import aRepr
144 144 aRepr.maxstring = 80
145 145 except:
146 146 # This is only a user-facing convenience, so any error we encounter
147 147 # here can be warned about but can be otherwise ignored. These
148 148 # printouts will tell us about problems if this API changes
149 149 import traceback
150 150 traceback.print_exc()
151 151
152 152 self.debugger = Pdb(colors)
153 153
154 154 def __call__(self):
155 155 """Starts an interactive debugger at the point where called.
156 156
157 157 This is similar to the pdb.set_trace() function from the std lib, but
158 158 using IPython's enhanced debugger."""
159 159
160 160 self.debugger.set_trace(sys._getframe().f_back)
161 161
162 162
163 163 def decorate_fn_with_doc(new_fn, old_fn, additional_text=""):
164 164 """Make new_fn have old_fn's doc string. This is particularly useful
165 165 for the ``do_...`` commands that hook into the help system.
166 166 Adapted from from a comp.lang.python posting
167 167 by Duncan Booth."""
168 168 def wrapper(*args, **kw):
169 169 return new_fn(*args, **kw)
170 170 if old_fn.__doc__:
171 171 wrapper.__doc__ = old_fn.__doc__ + additional_text
172 172 return wrapper
173 173
174 174
175 175 def _file_lines(fname):
176 176 """Return the contents of a named file as a list of lines.
177 177
178 178 This function never raises an IOError exception: if the file can't be
179 179 read, it simply returns an empty list."""
180 180
181 181 try:
182 182 outfile = open(fname)
183 183 except IOError:
184 184 return []
185 185 else:
186 186 out = outfile.readlines()
187 187 outfile.close()
188 188 return out
189 189
190 190
191 191 class Pdb(OldPdb):
192 192 """Modified Pdb class, does not load readline."""
193 193
194 194 def __init__(self,color_scheme='NoColor',completekey=None,
195 195 stdin=None, stdout=None):
196 196
197 197 # Parent constructor:
198 198 if has_pydb and completekey is None:
199 199 OldPdb.__init__(self,stdin=stdin,stdout=io.stdout)
200 200 else:
201 201 OldPdb.__init__(self,completekey,stdin,stdout)
202 202
203 203 self.prompt = prompt # The default prompt is '(Pdb)'
204 204
205 205 # IPython changes...
206 206 self.is_pydb = has_pydb
207 207
208 208 self.shell = ipapi.get()
209 209
210 210 if self.is_pydb:
211 211
212 212 # interactiveshell.py's ipalias seems to want pdb's checkline
213 213 # which located in pydb.fn
214 214 import pydb.fns
215 215 self.checkline = lambda filename, lineno: \
216 216 pydb.fns.checkline(self, filename, lineno)
217 217
218 218 self.curframe = None
219 219 self.do_restart = self.new_do_restart
220 220
221 221 self.old_all_completions = self.shell.Completer.all_completions
222 222 self.shell.Completer.all_completions=self.all_completions
223 223
224 224 self.do_list = decorate_fn_with_doc(self.list_command_pydb,
225 225 OldPdb.do_list)
226 226 self.do_l = self.do_list
227 227 self.do_frame = decorate_fn_with_doc(self.new_do_frame,
228 228 OldPdb.do_frame)
229 229
230 230 self.aliases = {}
231 231
232 232 # Create color table: we copy the default one from the traceback
233 233 # module and add a few attributes needed for debugging
234 234 self.color_scheme_table = exception_colors()
235 235
236 236 # shorthands
237 237 C = coloransi.TermColors
238 238 cst = self.color_scheme_table
239 239
240 240 cst['NoColor'].colors.breakpoint_enabled = C.NoColor
241 241 cst['NoColor'].colors.breakpoint_disabled = C.NoColor
242 242
243 243 cst['Linux'].colors.breakpoint_enabled = C.LightRed
244 244 cst['Linux'].colors.breakpoint_disabled = C.Red
245 245
246 246 cst['LightBG'].colors.breakpoint_enabled = C.LightRed
247 247 cst['LightBG'].colors.breakpoint_disabled = C.Red
248 248
249 249 self.set_colors(color_scheme)
250 250
251 251 # Add a python parser so we can syntax highlight source while
252 252 # debugging.
253 253 self.parser = PyColorize.Parser()
254 254
255 255 def set_colors(self, scheme):
256 256 """Shorthand access to the color table scheme selector method."""
257 257 self.color_scheme_table.set_active_scheme(scheme)
258 258
259 259 def interaction(self, frame, traceback):
260 260 self.shell.set_completer_frame(frame)
261 261 OldPdb.interaction(self, frame, traceback)
262 262
263 263 def new_do_up(self, arg):
264 264 OldPdb.do_up(self, arg)
265 265 self.shell.set_completer_frame(self.curframe)
266 266 do_u = do_up = decorate_fn_with_doc(new_do_up, OldPdb.do_up)
267 267
268 268 def new_do_down(self, arg):
269 269 OldPdb.do_down(self, arg)
270 270 self.shell.set_completer_frame(self.curframe)
271 271
272 272 do_d = do_down = decorate_fn_with_doc(new_do_down, OldPdb.do_down)
273 273
274 274 def new_do_frame(self, arg):
275 275 OldPdb.do_frame(self, arg)
276 276 self.shell.set_completer_frame(self.curframe)
277 277
278 278 def new_do_quit(self, arg):
279 279
280 280 if hasattr(self, 'old_all_completions'):
281 281 self.shell.Completer.all_completions=self.old_all_completions
282 282
283 283
284 284 return OldPdb.do_quit(self, arg)
285 285
286 286 do_q = do_quit = decorate_fn_with_doc(new_do_quit, OldPdb.do_quit)
287 287
288 288 def new_do_restart(self, arg):
289 289 """Restart command. In the context of ipython this is exactly the same
290 290 thing as 'quit'."""
291 291 self.msg("Restart doesn't make sense here. Using 'quit' instead.")
292 292 return self.do_quit(arg)
293 293
294 294 def postloop(self):
295 295 self.shell.set_completer_frame(None)
296 296
297 297 def print_stack_trace(self):
298 298 try:
299 299 for frame_lineno in self.stack:
300 300 self.print_stack_entry(frame_lineno, context = 5)
301 301 except KeyboardInterrupt:
302 302 pass
303 303
304 304 def print_stack_entry(self,frame_lineno,prompt_prefix='\n-> ',
305 305 context = 3):
306 306 #frame, lineno = frame_lineno
307 307 print(self.format_stack_entry(frame_lineno, '', context), file=io.stdout)
308 308
309 309 # vds: >>
310 310 frame, lineno = frame_lineno
311 311 filename = frame.f_code.co_filename
312 312 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
313 313 # vds: <<
314 314
315 315 def format_stack_entry(self, frame_lineno, lprefix=': ', context = 3):
316 316 import repr
317 317
318 318 ret = []
319 319
320 320 Colors = self.color_scheme_table.active_colors
321 321 ColorsNormal = Colors.Normal
322 322 tpl_link = u'%s%%s%s' % (Colors.filenameEm, ColorsNormal)
323 323 tpl_call = u'%s%%s%s%%s%s' % (Colors.vName, Colors.valEm, ColorsNormal)
324 324 tpl_line = u'%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
325 325 tpl_line_em = u'%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line,
326 326 ColorsNormal)
327 327
328 328 frame, lineno = frame_lineno
329 329
330 330 return_value = ''
331 331 if '__return__' in frame.f_locals:
332 332 rv = frame.f_locals['__return__']
333 333 #return_value += '->'
334 334 return_value += repr.repr(rv) + '\n'
335 335 ret.append(return_value)
336 336
337 337 #s = filename + '(' + `lineno` + ')'
338 338 filename = self.canonic(frame.f_code.co_filename)
339 339 link = tpl_link % py3compat.cast_unicode(filename)
340 340
341 341 if frame.f_code.co_name:
342 342 func = frame.f_code.co_name
343 343 else:
344 344 func = "<lambda>"
345 345
346 346 call = ''
347 347 if func != '?':
348 348 if '__args__' in frame.f_locals:
349 349 args = repr.repr(frame.f_locals['__args__'])
350 350 else:
351 351 args = '()'
352 352 call = tpl_call % (func, args)
353 353
354 354 # The level info should be generated in the same format pdb uses, to
355 355 # avoid breaking the pdbtrack functionality of python-mode in *emacs.
356 356 if frame is self.curframe:
357 357 ret.append('> ')
358 358 else:
359 359 ret.append(' ')
360 360 ret.append(u'%s(%s)%s\n' % (link,lineno,call))
361 361
362 362 start = lineno - 1 - context//2
363 363 lines = ulinecache.getlines(filename)
364 364 start = min(start, len(lines) - context)
365 365 start = max(start, 0)
366 366 lines = lines[start : start + context]
367 367
368 368 for i,line in enumerate(lines):
369 369 show_arrow = (start + 1 + i == lineno)
370 370 linetpl = (frame is self.curframe or show_arrow) \
371 371 and tpl_line_em \
372 372 or tpl_line
373 373 ret.append(self.__format_line(linetpl, filename,
374 374 start + 1 + i, line,
375 375 arrow = show_arrow) )
376 376 return ''.join(ret)
377 377
378 378 def __format_line(self, tpl_line, filename, lineno, line, arrow = False):
379 379 bp_mark = ""
380 380 bp_mark_color = ""
381 381
382 382 scheme = self.color_scheme_table.active_scheme_name
383 383 new_line, err = self.parser.format2(line, 'str', scheme)
384 384 if not err: line = new_line
385 385
386 386 bp = None
387 387 if lineno in self.get_file_breaks(filename):
388 388 bps = self.get_breaks(filename, lineno)
389 389 bp = bps[-1]
390 390
391 391 if bp:
392 392 Colors = self.color_scheme_table.active_colors
393 393 bp_mark = str(bp.number)
394 394 bp_mark_color = Colors.breakpoint_enabled
395 395 if not bp.enabled:
396 396 bp_mark_color = Colors.breakpoint_disabled
397 397
398 398 numbers_width = 7
399 399 if arrow:
400 400 # This is the line with the error
401 401 pad = numbers_width - len(str(lineno)) - len(bp_mark)
402 402 if pad >= 3:
403 403 marker = '-'*(pad-3) + '-> '
404 404 elif pad == 2:
405 405 marker = '> '
406 406 elif pad == 1:
407 407 marker = '>'
408 408 else:
409 409 marker = ''
410 410 num = '%s%s' % (marker, str(lineno))
411 411 line = tpl_line % (bp_mark_color + bp_mark, num, line)
412 412 else:
413 413 num = '%*s' % (numbers_width - len(bp_mark), str(lineno))
414 414 line = tpl_line % (bp_mark_color + bp_mark, num, line)
415 415
416 416 return line
417 417
418 418 def list_command_pydb(self, arg):
419 419 """List command to use if we have a newer pydb installed"""
420 420 filename, first, last = OldPdb.parse_list_cmd(self, arg)
421 421 if filename is not None:
422 422 self.print_list_lines(filename, first, last)
423 423
424 424 def print_list_lines(self, filename, first, last):
425 425 """The printing (as opposed to the parsing part of a 'list'
426 426 command."""
427 427 try:
428 428 Colors = self.color_scheme_table.active_colors
429 429 ColorsNormal = Colors.Normal
430 430 tpl_line = '%%s%s%%s %s%%s' % (Colors.lineno, ColorsNormal)
431 431 tpl_line_em = '%%s%s%%s %s%%s%s' % (Colors.linenoEm, Colors.line, ColorsNormal)
432 432 src = []
433 433 if filename == "<string>" and hasattr(self, "_exec_filename"):
434 434 filename = self._exec_filename
435 435
436 436 for lineno in range(first, last+1):
437 437 line = ulinecache.getline(filename, lineno)
438 438 if not line:
439 439 break
440 440
441 441 if lineno == self.curframe.f_lineno:
442 442 line = self.__format_line(tpl_line_em, filename, lineno, line, arrow = True)
443 443 else:
444 444 line = self.__format_line(tpl_line, filename, lineno, line, arrow = False)
445 445
446 446 src.append(line)
447 447 self.lineno = lineno
448 448
449 449 print(''.join(src), file=io.stdout)
450 450
451 451 except KeyboardInterrupt:
452 452 pass
453 453
454 454 def do_list(self, arg):
455 455 self.lastcmd = 'list'
456 456 last = None
457 457 if arg:
458 458 try:
459 459 x = eval(arg, {}, {})
460 460 if type(x) == type(()):
461 461 first, last = x
462 462 first = int(first)
463 463 last = int(last)
464 464 if last < first:
465 465 # Assume it's a count
466 466 last = first + last
467 467 else:
468 468 first = max(1, int(x) - 5)
469 469 except:
470 470 print('*** Error in argument:', repr(arg))
471 471 return
472 472 elif self.lineno is None:
473 473 first = max(1, self.curframe.f_lineno - 5)
474 474 else:
475 475 first = self.lineno + 1
476 476 if last is None:
477 477 last = first + 10
478 478 self.print_list_lines(self.curframe.f_code.co_filename, first, last)
479 479
480 480 # vds: >>
481 481 lineno = first
482 482 filename = self.curframe.f_code.co_filename
483 483 self.shell.hooks.synchronize_with_editor(filename, lineno, 0)
484 484 # vds: <<
485 485
486 486 do_l = do_list
487 487
488 488 def do_pdef(self, arg):
489 489 """Print the call signature for any callable object.
490 490
491 491 The debugger interface to %pdef"""
492 492 namespaces = [('Locals', self.curframe.f_locals),
493 493 ('Globals', self.curframe.f_globals)]
494 494 self.shell.find_line_magic('pdef')(arg, namespaces=namespaces)
495 495
496 496 def do_pdoc(self, arg):
497 497 """Print the docstring for an object.
498 498
499 499 The debugger interface to %pdoc."""
500 500 namespaces = [('Locals', self.curframe.f_locals),
501 501 ('Globals', self.curframe.f_globals)]
502 502 self.shell.find_line_magic('pdoc')(arg, namespaces=namespaces)
503 503
504 504 def do_pfile(self, arg):
505 505 """Print (or run through pager) the file where an object is defined.
506 506
507 507 The debugger interface to %pfile.
508 508 """
509 509 namespaces = [('Locals', self.curframe.f_locals),
510 510 ('Globals', self.curframe.f_globals)]
511 511 self.shell.find_line_magic('pfile')(arg, namespaces=namespaces)
512 512
513 513 def do_pinfo(self, arg):
514 514 """Provide detailed information about an object.
515 515
516 516 The debugger interface to %pinfo, i.e., obj?."""
517 517 namespaces = [('Locals', self.curframe.f_locals),
518 518 ('Globals', self.curframe.f_globals)]
519 519 self.shell.find_line_magic('pinfo')(arg, namespaces=namespaces)
520 520
521 521 def do_pinfo2(self, arg):
522 522 """Provide extra detailed information about an object.
523 523
524 524 The debugger interface to %pinfo2, i.e., obj??."""
525 525 namespaces = [('Locals', self.curframe.f_locals),
526 526 ('Globals', self.curframe.f_globals)]
527 527 self.shell.find_line_magic('pinfo2')(arg, namespaces=namespaces)
528 528
529 529 def do_psource(self, arg):
530 530 """Print (or run through pager) the source code for an object."""
531 531 namespaces = [('Locals', self.curframe.f_locals),
532 532 ('Globals', self.curframe.f_globals)]
533 533 self.shell.find_line_magic('psource')(arg, namespaces=namespaces)
534 534
535 535 def checkline(self, filename, lineno):
536 536 """Check whether specified line seems to be executable.
537 537
538 538 Return `lineno` if it is, 0 if not (e.g. a docstring, comment, blank
539 539 line or EOF). Warning: testing is not comprehensive.
540 540 """
541 541 #######################################################################
542 542 # XXX Hack! Use python-2.5 compatible code for this call, because with
543 543 # all of our changes, we've drifted from the pdb api in 2.6. For now,
544 544 # changing:
545 545 #
546 546 #line = linecache.getline(filename, lineno, self.curframe.f_globals)
547 547 # to:
548 548 #
549 549 line = linecache.getline(filename, lineno)
550 550 #
551 551 # does the trick. But in reality, we need to fix this by reconciling
552 552 # our updates with the new Pdb APIs in Python 2.6.
553 553 #
554 554 # End hack. The rest of this method is copied verbatim from 2.6 pdb.py
555 555 #######################################################################
556 556
557 557 if not line:
558 558 print('End of file', file=self.stdout)
559 559 return 0
560 560 line = line.strip()
561 561 # Don't allow setting breakpoint at a blank line
562 562 if (not line or (line[0] == '#') or
563 563 (line[:3] == '"""') or line[:3] == "'''"):
564 564 print('*** Blank or comment', file=self.stdout)
565 565 return 0
566 566 return lineno
@@ -1,275 +1,275 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Displayhook for IPython.
3 3
4 4 This defines a callable class that IPython uses for `sys.displayhook`.
5 5
6 6 Authors:
7 7
8 8 * Fernando Perez
9 9 * Brian Granger
10 10 * Robert Kern
11 11 """
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Copyright (C) 2008-2011 The IPython Development Team
15 15 # Copyright (C) 2001-2007 Fernando Perez <fperez@colorado.edu>
16 16 #
17 17 # Distributed under the terms of the BSD License. The full license is in
18 18 # the file COPYING, distributed as part of this software.
19 19 #-----------------------------------------------------------------------------
20 20
21 21 #-----------------------------------------------------------------------------
22 22 # Imports
23 23 #-----------------------------------------------------------------------------
24 24 from __future__ import print_function
25 25
26 26 import __builtin__
27 27
28 28 import sys
29 29
30 30
31 31 from IPython.config.configurable import Configurable
32 32 from IPython.utils import io
33 from IPython.utils.traitlets import Instance, List
33 from IPython.utils.traitlets import Instance
34 34 from IPython.utils.warn import warn
35 35
36 36 #-----------------------------------------------------------------------------
37 37 # Main displayhook class
38 38 #-----------------------------------------------------------------------------
39 39
40 40 # TODO: Move the various attributes (cache_size, [others now moved]). Some
41 41 # of these are also attributes of InteractiveShell. They should be on ONE object
42 42 # only and the other objects should ask that one object for their values.
43 43
44 44 class DisplayHook(Configurable):
45 45 """The custom IPython displayhook to replace sys.displayhook.
46 46
47 47 This class does many things, but the basic idea is that it is a callable
48 48 that gets called anytime user code returns a value.
49 49 """
50 50
51 51 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
52 52
53 53 def __init__(self, shell=None, cache_size=1000, config=None):
54 54 super(DisplayHook, self).__init__(shell=shell, config=config)
55 55
56 56 cache_size_min = 3
57 57 if cache_size <= 0:
58 58 self.do_full_cache = 0
59 59 cache_size = 0
60 60 elif cache_size < cache_size_min:
61 61 self.do_full_cache = 0
62 62 cache_size = 0
63 63 warn('caching was disabled (min value for cache size is %s).' %
64 64 cache_size_min,level=3)
65 65 else:
66 66 self.do_full_cache = 1
67 67
68 68 self.cache_size = cache_size
69 69
70 70 # we need a reference to the user-level namespace
71 71 self.shell = shell
72 72
73 73 self._,self.__,self.___ = '','',''
74 74
75 75 # these are deliberately global:
76 76 to_user_ns = {'_':self._,'__':self.__,'___':self.___}
77 77 self.shell.user_ns.update(to_user_ns)
78 78
79 79 @property
80 80 def prompt_count(self):
81 81 return self.shell.execution_count
82 82
83 83 #-------------------------------------------------------------------------
84 84 # Methods used in __call__. Override these methods to modify the behavior
85 85 # of the displayhook.
86 86 #-------------------------------------------------------------------------
87 87
88 88 def check_for_underscore(self):
89 89 """Check if the user has set the '_' variable by hand."""
90 90 # If something injected a '_' variable in __builtin__, delete
91 91 # ipython's automatic one so we don't clobber that. gettext() in
92 92 # particular uses _, so we need to stay away from it.
93 93 if '_' in __builtin__.__dict__:
94 94 try:
95 95 del self.shell.user_ns['_']
96 96 except KeyError:
97 97 pass
98 98
99 99 def quiet(self):
100 100 """Should we silence the display hook because of ';'?"""
101 101 # do not print output if input ends in ';'
102 102 try:
103 103 cell = self.shell.history_manager.input_hist_parsed[self.prompt_count]
104 104 if cell.rstrip().endswith(';'):
105 105 return True
106 106 except IndexError:
107 107 # some uses of ipshellembed may fail here
108 108 pass
109 109 return False
110 110
111 111 def start_displayhook(self):
112 112 """Start the displayhook, initializing resources."""
113 113 pass
114 114
115 115 def write_output_prompt(self):
116 116 """Write the output prompt.
117 117
118 118 The default implementation simply writes the prompt to
119 119 ``io.stdout``.
120 120 """
121 121 # Use write, not print which adds an extra space.
122 122 io.stdout.write(self.shell.separate_out)
123 123 outprompt = self.shell.prompt_manager.render('out')
124 124 if self.do_full_cache:
125 125 io.stdout.write(outprompt)
126 126
127 127 def compute_format_data(self, result):
128 128 """Compute format data of the object to be displayed.
129 129
130 130 The format data is a generalization of the :func:`repr` of an object.
131 131 In the default implementation the format data is a :class:`dict` of
132 132 key value pair where the keys are valid MIME types and the values
133 133 are JSON'able data structure containing the raw data for that MIME
134 134 type. It is up to frontends to determine pick a MIME to to use and
135 135 display that data in an appropriate manner.
136 136
137 137 This method only computes the format data for the object and should
138 138 NOT actually print or write that to a stream.
139 139
140 140 Parameters
141 141 ----------
142 142 result : object
143 143 The Python object passed to the display hook, whose format will be
144 144 computed.
145 145
146 146 Returns
147 147 -------
148 148 format_data : dict
149 149 A :class:`dict` whose keys are valid MIME types and values are
150 150 JSON'able raw data for that MIME type. It is recommended that
151 151 all return values of this should always include the "text/plain"
152 152 MIME type representation of the object.
153 153 """
154 154 return self.shell.display_formatter.format(result)
155 155
156 156 def write_format_data(self, format_dict):
157 157 """Write the format data dict to the frontend.
158 158
159 159 This default version of this method simply writes the plain text
160 160 representation of the object to ``io.stdout``. Subclasses should
161 161 override this method to send the entire `format_dict` to the
162 162 frontends.
163 163
164 164 Parameters
165 165 ----------
166 166 format_dict : dict
167 167 The format dict for the object passed to `sys.displayhook`.
168 168 """
169 169 # We want to print because we want to always make sure we have a
170 170 # newline, even if all the prompt separators are ''. This is the
171 171 # standard IPython behavior.
172 172 result_repr = format_dict['text/plain']
173 173 if '\n' in result_repr:
174 174 # So that multi-line strings line up with the left column of
175 175 # the screen, instead of having the output prompt mess up
176 176 # their first line.
177 177 # We use the prompt template instead of the expanded prompt
178 178 # because the expansion may add ANSI escapes that will interfere
179 179 # with our ability to determine whether or not we should add
180 180 # a newline.
181 181 prompt_template = self.shell.prompt_manager.out_template
182 182 if prompt_template and not prompt_template.endswith('\n'):
183 183 # But avoid extraneous empty lines.
184 184 result_repr = '\n' + result_repr
185 185
186 186 print(result_repr, file=io.stdout)
187 187
188 188 def update_user_ns(self, result):
189 189 """Update user_ns with various things like _, __, _1, etc."""
190 190
191 191 # Avoid recursive reference when displaying _oh/Out
192 192 if result is not self.shell.user_ns['_oh']:
193 193 if len(self.shell.user_ns['_oh']) >= self.cache_size and self.do_full_cache:
194 194 warn('Output cache limit (currently '+
195 195 repr(self.cache_size)+' entries) hit.\n'
196 196 'Flushing cache and resetting history counter...\n'
197 197 'The only history variables available will be _,__,___ and _1\n'
198 198 'with the current result.')
199 199
200 200 self.flush()
201 201 # Don't overwrite '_' and friends if '_' is in __builtin__ (otherwise
202 202 # we cause buggy behavior for things like gettext).
203 203
204 204 if '_' not in __builtin__.__dict__:
205 205 self.___ = self.__
206 206 self.__ = self._
207 207 self._ = result
208 208 self.shell.push({'_':self._,
209 209 '__':self.__,
210 210 '___':self.___}, interactive=False)
211 211
212 212 # hackish access to top-level namespace to create _1,_2... dynamically
213 213 to_main = {}
214 214 if self.do_full_cache:
215 215 new_result = '_'+repr(self.prompt_count)
216 216 to_main[new_result] = result
217 217 self.shell.push(to_main, interactive=False)
218 218 self.shell.user_ns['_oh'][self.prompt_count] = result
219 219
220 220 def log_output(self, format_dict):
221 221 """Log the output."""
222 222 if self.shell.logger.log_output:
223 223 self.shell.logger.log_write(format_dict['text/plain'], 'output')
224 224 self.shell.history_manager.output_hist_reprs[self.prompt_count] = \
225 225 format_dict['text/plain']
226 226
227 227 def finish_displayhook(self):
228 228 """Finish up all displayhook activities."""
229 229 io.stdout.write(self.shell.separate_out2)
230 230 io.stdout.flush()
231 231
232 232 def __call__(self, result=None):
233 233 """Printing with history cache management.
234 234
235 235 This is invoked everytime the interpreter needs to print, and is
236 236 activated by setting the variable sys.displayhook to it.
237 237 """
238 238 self.check_for_underscore()
239 239 if result is not None and not self.quiet():
240 240 self.start_displayhook()
241 241 self.write_output_prompt()
242 242 format_dict = self.compute_format_data(result)
243 243 self.write_format_data(format_dict)
244 244 self.update_user_ns(result)
245 245 self.log_output(format_dict)
246 246 self.finish_displayhook()
247 247
248 248 def flush(self):
249 249 if not self.do_full_cache:
250 250 raise ValueError("You shouldn't have reached the cache flush "
251 251 "if full caching is not enabled!")
252 252 # delete auto-generated vars from global namespace
253 253
254 254 for n in range(1,self.prompt_count + 1):
255 255 key = '_'+repr(n)
256 256 try:
257 257 del self.shell.user_ns[key]
258 258 except: pass
259 259 # In some embedded circumstances, the user_ns doesn't have the
260 260 # '_oh' key set up.
261 261 oh = self.shell.user_ns.get('_oh', None)
262 262 if oh is not None:
263 263 oh.clear()
264 264
265 265 # Release our own references to objects:
266 266 self._, self.__, self.___ = '', '', ''
267 267
268 268 if '_' not in __builtin__.__dict__:
269 269 self.shell.user_ns.update({'_':None,'__':None, '___':None})
270 270 import gc
271 271 # TODO: Is this really needed?
272 272 # IronPython blocks here forever
273 273 if sys.platform != "cli":
274 274 gc.collect()
275 275
@@ -1,60 +1,59 b''
1 1 """Support for interactive macros in IPython"""
2 2
3 3 #*****************************************************************************
4 4 # Copyright (C) 2001-2005 Fernando Perez <fperez@colorado.edu>
5 5 #
6 6 # Distributed under the terms of the BSD License. The full license is in
7 7 # the file COPYING, distributed as part of this software.
8 8 #*****************************************************************************
9 9
10 10 import re
11 import sys
12 11
13 12 from IPython.utils import py3compat
14 13 from IPython.utils.encoding import DEFAULT_ENCODING
15 14
16 15 coding_declaration = re.compile(r"#\s*coding[:=]\s*([-\w.]+)")
17 16
18 17 class Macro(object):
19 18 """Simple class to store the value of macros as strings.
20 19
21 20 Macro is just a callable that executes a string of IPython
22 21 input when called.
23 22
24 23 Args to macro are available in _margv list if you need them.
25 24 """
26 25
27 26 def __init__(self,code):
28 27 """store the macro value, as a single string which can be executed"""
29 28 lines = []
30 29 enc = None
31 30 for line in code.splitlines():
32 31 coding_match = coding_declaration.match(line)
33 32 if coding_match:
34 33 enc = coding_match.group(1)
35 34 else:
36 35 lines.append(line)
37 36 code = "\n".join(lines)
38 37 if isinstance(code, bytes):
39 38 code = code.decode(enc or DEFAULT_ENCODING)
40 39 self.value = code + '\n'
41 40
42 41 def __str__(self):
43 42 return py3compat.unicode_to_str(self.value)
44 43
45 44 def __unicode__(self):
46 45 return self.value
47 46
48 47 def __repr__(self):
49 48 return 'IPython.macro.Macro(%s)' % repr(self.value)
50 49
51 50 def __getstate__(self):
52 51 """ needed for safe pickling via %store """
53 52 return {'value': self.value}
54 53
55 54 def __add__(self, other):
56 55 if isinstance(other, Macro):
57 56 return Macro(self.value + other.value)
58 57 elif isinstance(other, basestring):
59 58 return Macro(self.value + other)
60 59 raise TypeError
@@ -1,683 +1,683 b''
1 1 # encoding: utf-8
2 2 """Magic functions for InteractiveShell.
3 3 """
4 4
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de> and
7 7 # Copyright (C) 2001 Fernando Perez <fperez@colorado.edu>
8 8 # Copyright (C) 2008 The IPython Development Team
9 9
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #-----------------------------------------------------------------------------
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Imports
16 16 #-----------------------------------------------------------------------------
17 17 # Stdlib
18 18 import os
19 19 import re
20 20 import sys
21 21 import types
22 22 from getopt import getopt, GetoptError
23 23
24 24 # Our own
25 25 from IPython.config.configurable import Configurable
26 26 from IPython.core import oinspect
27 27 from IPython.core.error import UsageError
28 28 from IPython.core.inputsplitter import ESC_MAGIC, ESC_MAGIC2
29 29 from IPython.external.decorator import decorator
30 30 from IPython.utils.ipstruct import Struct
31 31 from IPython.utils.process import arg_split
32 32 from IPython.utils.text import dedent
33 33 from IPython.utils.traitlets import Bool, Dict, Instance, MetaHasTraits
34 from IPython.utils.warn import error, warn
34 from IPython.utils.warn import error
35 35
36 36 #-----------------------------------------------------------------------------
37 37 # Globals
38 38 #-----------------------------------------------------------------------------
39 39
40 40 # A dict we'll use for each class that has magics, used as temporary storage to
41 41 # pass information between the @line/cell_magic method decorators and the
42 42 # @magics_class class decorator, because the method decorators have no
43 43 # access to the class when they run. See for more details:
44 44 # http://stackoverflow.com/questions/2366713/can-a-python-decorator-of-an-instance-method-access-the-class
45 45
46 46 magics = dict(line={}, cell={})
47 47
48 48 magic_kinds = ('line', 'cell')
49 49 magic_spec = ('line', 'cell', 'line_cell')
50 50 magic_escapes = dict(line=ESC_MAGIC, cell=ESC_MAGIC2)
51 51
52 52 #-----------------------------------------------------------------------------
53 53 # Utility classes and functions
54 54 #-----------------------------------------------------------------------------
55 55
56 56 class Bunch: pass
57 57
58 58
59 59 def on_off(tag):
60 60 """Return an ON/OFF string for a 1/0 input. Simple utility function."""
61 61 return ['OFF','ON'][tag]
62 62
63 63
64 64 def compress_dhist(dh):
65 65 """Compress a directory history into a new one with at most 20 entries.
66 66
67 67 Return a new list made from the first and last 10 elements of dhist after
68 68 removal of duplicates.
69 69 """
70 70 head, tail = dh[:-10], dh[-10:]
71 71
72 72 newhead = []
73 73 done = set()
74 74 for h in head:
75 75 if h in done:
76 76 continue
77 77 newhead.append(h)
78 78 done.add(h)
79 79
80 80 return newhead + tail
81 81
82 82
83 83 def needs_local_scope(func):
84 84 """Decorator to mark magic functions which need to local scope to run."""
85 85 func.needs_local_scope = True
86 86 return func
87 87
88 88 #-----------------------------------------------------------------------------
89 89 # Class and method decorators for registering magics
90 90 #-----------------------------------------------------------------------------
91 91
92 92 def magics_class(cls):
93 93 """Class decorator for all subclasses of the main Magics class.
94 94
95 95 Any class that subclasses Magics *must* also apply this decorator, to
96 96 ensure that all the methods that have been decorated as line/cell magics
97 97 get correctly registered in the class instance. This is necessary because
98 98 when method decorators run, the class does not exist yet, so they
99 99 temporarily store their information into a module global. Application of
100 100 this class decorator copies that global data to the class instance and
101 101 clears the global.
102 102
103 103 Obviously, this mechanism is not thread-safe, which means that the
104 104 *creation* of subclasses of Magic should only be done in a single-thread
105 105 context. Instantiation of the classes has no restrictions. Given that
106 106 these classes are typically created at IPython startup time and before user
107 107 application code becomes active, in practice this should not pose any
108 108 problems.
109 109 """
110 110 cls.registered = True
111 111 cls.magics = dict(line = magics['line'],
112 112 cell = magics['cell'])
113 113 magics['line'] = {}
114 114 magics['cell'] = {}
115 115 return cls
116 116
117 117
118 118 def record_magic(dct, magic_kind, magic_name, func):
119 119 """Utility function to store a function as a magic of a specific kind.
120 120
121 121 Parameters
122 122 ----------
123 123 dct : dict
124 124 A dictionary with 'line' and 'cell' subdicts.
125 125
126 126 magic_kind : str
127 127 Kind of magic to be stored.
128 128
129 129 magic_name : str
130 130 Key to store the magic as.
131 131
132 132 func : function
133 133 Callable object to store.
134 134 """
135 135 if magic_kind == 'line_cell':
136 136 dct['line'][magic_name] = dct['cell'][magic_name] = func
137 137 else:
138 138 dct[magic_kind][magic_name] = func
139 139
140 140
141 141 def validate_type(magic_kind):
142 142 """Ensure that the given magic_kind is valid.
143 143
144 144 Check that the given magic_kind is one of the accepted spec types (stored
145 145 in the global `magic_spec`), raise ValueError otherwise.
146 146 """
147 147 if magic_kind not in magic_spec:
148 148 raise ValueError('magic_kind must be one of %s, %s given' %
149 149 magic_kinds, magic_kind)
150 150
151 151
152 152 # The docstrings for the decorator below will be fairly similar for the two
153 153 # types (method and function), so we generate them here once and reuse the
154 154 # templates below.
155 155 _docstring_template = \
156 156 """Decorate the given {0} as {1} magic.
157 157
158 158 The decorator can be used with or without arguments, as follows.
159 159
160 160 i) without arguments: it will create a {1} magic named as the {0} being
161 161 decorated::
162 162
163 163 @deco
164 164 def foo(...)
165 165
166 166 will create a {1} magic named `foo`.
167 167
168 168 ii) with one string argument: which will be used as the actual name of the
169 169 resulting magic::
170 170
171 171 @deco('bar')
172 172 def foo(...)
173 173
174 174 will create a {1} magic named `bar`.
175 175 """
176 176
177 177 # These two are decorator factories. While they are conceptually very similar,
178 178 # there are enough differences in the details that it's simpler to have them
179 179 # written as completely standalone functions rather than trying to share code
180 180 # and make a single one with convoluted logic.
181 181
182 182 def _method_magic_marker(magic_kind):
183 183 """Decorator factory for methods in Magics subclasses.
184 184 """
185 185
186 186 validate_type(magic_kind)
187 187
188 188 # This is a closure to capture the magic_kind. We could also use a class,
189 189 # but it's overkill for just that one bit of state.
190 190 def magic_deco(arg):
191 191 call = lambda f, *a, **k: f(*a, **k)
192 192
193 193 if callable(arg):
194 194 # "Naked" decorator call (just @foo, no args)
195 195 func = arg
196 196 name = func.func_name
197 197 retval = decorator(call, func)
198 198 record_magic(magics, magic_kind, name, name)
199 199 elif isinstance(arg, basestring):
200 200 # Decorator called with arguments (@foo('bar'))
201 201 name = arg
202 202 def mark(func, *a, **kw):
203 203 record_magic(magics, magic_kind, name, func.func_name)
204 204 return decorator(call, func)
205 205 retval = mark
206 206 else:
207 207 raise TypeError("Decorator can only be called with "
208 208 "string or function")
209 209 return retval
210 210
211 211 # Ensure the resulting decorator has a usable docstring
212 212 magic_deco.__doc__ = _docstring_template.format('method', magic_kind)
213 213 return magic_deco
214 214
215 215
216 216 def _function_magic_marker(magic_kind):
217 217 """Decorator factory for standalone functions.
218 218 """
219 219 validate_type(magic_kind)
220 220
221 221 # This is a closure to capture the magic_kind. We could also use a class,
222 222 # but it's overkill for just that one bit of state.
223 223 def magic_deco(arg):
224 224 call = lambda f, *a, **k: f(*a, **k)
225 225
226 226 # Find get_ipython() in the caller's namespace
227 227 caller = sys._getframe(1)
228 228 for ns in ['f_locals', 'f_globals', 'f_builtins']:
229 229 get_ipython = getattr(caller, ns).get('get_ipython')
230 230 if get_ipython is not None:
231 231 break
232 232 else:
233 233 raise NameError('Decorator can only run in context where '
234 234 '`get_ipython` exists')
235 235
236 236 ip = get_ipython()
237 237
238 238 if callable(arg):
239 239 # "Naked" decorator call (just @foo, no args)
240 240 func = arg
241 241 name = func.func_name
242 242 ip.register_magic_function(func, magic_kind, name)
243 243 retval = decorator(call, func)
244 244 elif isinstance(arg, basestring):
245 245 # Decorator called with arguments (@foo('bar'))
246 246 name = arg
247 247 def mark(func, *a, **kw):
248 248 ip.register_magic_function(func, magic_kind, name)
249 249 return decorator(call, func)
250 250 retval = mark
251 251 else:
252 252 raise TypeError("Decorator can only be called with "
253 253 "string or function")
254 254 return retval
255 255
256 256 # Ensure the resulting decorator has a usable docstring
257 257 ds = _docstring_template.format('function', magic_kind)
258 258
259 259 ds += dedent("""
260 260 Note: this decorator can only be used in a context where IPython is already
261 261 active, so that the `get_ipython()` call succeeds. You can therefore use
262 262 it in your startup files loaded after IPython initializes, but *not* in the
263 263 IPython configuration file itself, which is executed before IPython is
264 264 fully up and running. Any file located in the `startup` subdirectory of
265 265 your configuration profile will be OK in this sense.
266 266 """)
267 267
268 268 magic_deco.__doc__ = ds
269 269 return magic_deco
270 270
271 271
272 272 # Create the actual decorators for public use
273 273
274 274 # These three are used to decorate methods in class definitions
275 275 line_magic = _method_magic_marker('line')
276 276 cell_magic = _method_magic_marker('cell')
277 277 line_cell_magic = _method_magic_marker('line_cell')
278 278
279 279 # These three decorate standalone functions and perform the decoration
280 280 # immediately. They can only run where get_ipython() works
281 281 register_line_magic = _function_magic_marker('line')
282 282 register_cell_magic = _function_magic_marker('cell')
283 283 register_line_cell_magic = _function_magic_marker('line_cell')
284 284
285 285 #-----------------------------------------------------------------------------
286 286 # Core Magic classes
287 287 #-----------------------------------------------------------------------------
288 288
289 289 class MagicsManager(Configurable):
290 290 """Object that handles all magic-related functionality for IPython.
291 291 """
292 292 # Non-configurable class attributes
293 293
294 294 # A two-level dict, first keyed by magic type, then by magic function, and
295 295 # holding the actual callable object as value. This is the dict used for
296 296 # magic function dispatch
297 297 magics = Dict
298 298
299 299 # A registry of the original objects that we've been given holding magics.
300 300 registry = Dict
301 301
302 302 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
303 303
304 304 auto_magic = Bool(True, config=True, help=
305 305 "Automatically call line magics without requiring explicit % prefix")
306 306
307 307 _auto_status = [
308 308 'Automagic is OFF, % prefix IS needed for line magics.',
309 309 'Automagic is ON, % prefix IS NOT needed for line magics.']
310 310
311 311 user_magics = Instance('IPython.core.magics.UserMagics')
312 312
313 313 def __init__(self, shell=None, config=None, user_magics=None, **traits):
314 314
315 315 super(MagicsManager, self).__init__(shell=shell, config=config,
316 316 user_magics=user_magics, **traits)
317 317 self.magics = dict(line={}, cell={})
318 318 # Let's add the user_magics to the registry for uniformity, so *all*
319 319 # registered magic containers can be found there.
320 320 self.registry[user_magics.__class__.__name__] = user_magics
321 321
322 322 def auto_status(self):
323 323 """Return descriptive string with automagic status."""
324 324 return self._auto_status[self.auto_magic]
325 325
326 326 def lsmagic_info(self):
327 327 magic_list = []
328 328 for m_type in self.magics :
329 329 for m_name,mgc in self.magics[m_type].items():
330 330 try :
331 331 magic_list.append({'name':m_name,'type':m_type,'class':mgc.im_class.__name__})
332 332 except AttributeError :
333 333 magic_list.append({'name':m_name,'type':m_type,'class':'Other'})
334 334 return magic_list
335 335
336 336 def lsmagic(self):
337 337 """Return a dict of currently available magic functions.
338 338
339 339 The return dict has the keys 'line' and 'cell', corresponding to the
340 340 two types of magics we support. Each value is a list of names.
341 341 """
342 342 return self.magics
343 343
344 344 def lsmagic_docs(self, brief=False, missing=''):
345 345 """Return dict of documentation of magic functions.
346 346
347 347 The return dict has the keys 'line' and 'cell', corresponding to the
348 348 two types of magics we support. Each value is a dict keyed by magic
349 349 name whose value is the function docstring. If a docstring is
350 350 unavailable, the value of `missing` is used instead.
351 351
352 352 If brief is True, only the first line of each docstring will be returned.
353 353 """
354 354 docs = {}
355 355 for m_type in self.magics:
356 356 m_docs = {}
357 357 for m_name, m_func in self.magics[m_type].iteritems():
358 358 if m_func.__doc__:
359 359 if brief:
360 360 m_docs[m_name] = m_func.__doc__.split('\n', 1)[0]
361 361 else:
362 362 m_docs[m_name] = m_func.__doc__.rstrip()
363 363 else:
364 364 m_docs[m_name] = missing
365 365 docs[m_type] = m_docs
366 366 return docs
367 367
368 368 def register(self, *magic_objects):
369 369 """Register one or more instances of Magics.
370 370
371 371 Take one or more classes or instances of classes that subclass the main
372 372 `core.Magic` class, and register them with IPython to use the magic
373 373 functions they provide. The registration process will then ensure that
374 374 any methods that have decorated to provide line and/or cell magics will
375 375 be recognized with the `%x`/`%%x` syntax as a line/cell magic
376 376 respectively.
377 377
378 378 If classes are given, they will be instantiated with the default
379 379 constructor. If your classes need a custom constructor, you should
380 380 instanitate them first and pass the instance.
381 381
382 382 The provided arguments can be an arbitrary mix of classes and instances.
383 383
384 384 Parameters
385 385 ----------
386 386 magic_objects : one or more classes or instances
387 387 """
388 388 # Start by validating them to ensure they have all had their magic
389 389 # methods registered at the instance level
390 390 for m in magic_objects:
391 391 if not m.registered:
392 392 raise ValueError("Class of magics %r was constructed without "
393 393 "the @register_magics class decorator")
394 394 if type(m) in (type, MetaHasTraits):
395 395 # If we're given an uninstantiated class
396 396 m = m(shell=self.shell)
397 397
398 398 # Now that we have an instance, we can register it and update the
399 399 # table of callables
400 400 self.registry[m.__class__.__name__] = m
401 401 for mtype in magic_kinds:
402 402 self.magics[mtype].update(m.magics[mtype])
403 403
404 404 def register_function(self, func, magic_kind='line', magic_name=None):
405 405 """Expose a standalone function as magic function for IPython.
406 406
407 407 This will create an IPython magic (line, cell or both) from a
408 408 standalone function. The functions should have the following
409 409 signatures:
410 410
411 411 * For line magics: `def f(line)`
412 412 * For cell magics: `def f(line, cell)`
413 413 * For a function that does both: `def f(line, cell=None)`
414 414
415 415 In the latter case, the function will be called with `cell==None` when
416 416 invoked as `%f`, and with cell as a string when invoked as `%%f`.
417 417
418 418 Parameters
419 419 ----------
420 420 func : callable
421 421 Function to be registered as a magic.
422 422
423 423 magic_kind : str
424 424 Kind of magic, one of 'line', 'cell' or 'line_cell'
425 425
426 426 magic_name : optional str
427 427 If given, the name the magic will have in the IPython namespace. By
428 428 default, the name of the function itself is used.
429 429 """
430 430
431 431 # Create the new method in the user_magics and register it in the
432 432 # global table
433 433 validate_type(magic_kind)
434 434 magic_name = func.func_name if magic_name is None else magic_name
435 435 setattr(self.user_magics, magic_name, func)
436 436 record_magic(self.magics, magic_kind, magic_name, func)
437 437
438 438 def define_magic(self, name, func):
439 439 """[Deprecated] Expose own function as magic function for IPython.
440 440
441 441 Example::
442 442
443 443 def foo_impl(self, parameter_s=''):
444 444 'My very own magic!. (Use docstrings, IPython reads them).'
445 445 print 'Magic function. Passed parameter is between < >:'
446 446 print '<%s>' % parameter_s
447 447 print 'The self object is:', self
448 448
449 449 ip.define_magic('foo',foo_impl)
450 450 """
451 451 meth = types.MethodType(func, self.user_magics)
452 452 setattr(self.user_magics, name, meth)
453 453 record_magic(self.magics, 'line', name, meth)
454 454
455 455 def register_alias(self, alias_name, magic_name, magic_kind='line'):
456 456 """Register an alias to a magic function.
457 457
458 458 The alias is an instance of :class:`MagicAlias`, which holds the
459 459 name and kind of the magic it should call. Binding is done at
460 460 call time, so if the underlying magic function is changed the alias
461 461 will call the new function.
462 462
463 463 Parameters
464 464 ----------
465 465 alias_name : str
466 466 The name of the magic to be registered.
467 467
468 468 magic_name : str
469 469 The name of an existing magic.
470 470
471 471 magic_kind : str
472 472 Kind of magic, one of 'line' or 'cell'
473 473 """
474 474
475 475 # `validate_type` is too permissive, as it allows 'line_cell'
476 476 # which we do not handle.
477 477 if magic_kind not in magic_kinds:
478 478 raise ValueError('magic_kind must be one of %s, %s given' %
479 479 magic_kinds, magic_kind)
480 480
481 481 alias = MagicAlias(self.shell, magic_name, magic_kind)
482 482 setattr(self.user_magics, alias_name, alias)
483 483 record_magic(self.magics, magic_kind, alias_name, alias)
484 484
485 485 # Key base class that provides the central functionality for magics.
486 486
487 487 class Magics(object):
488 488 """Base class for implementing magic functions.
489 489
490 490 Shell functions which can be reached as %function_name. All magic
491 491 functions should accept a string, which they can parse for their own
492 492 needs. This can make some functions easier to type, eg `%cd ../`
493 493 vs. `%cd("../")`
494 494
495 495 Classes providing magic functions need to subclass this class, and they
496 496 MUST:
497 497
498 498 - Use the method decorators `@line_magic` and `@cell_magic` to decorate
499 499 individual methods as magic functions, AND
500 500
501 501 - Use the class decorator `@magics_class` to ensure that the magic
502 502 methods are properly registered at the instance level upon instance
503 503 initialization.
504 504
505 505 See :mod:`magic_functions` for examples of actual implementation classes.
506 506 """
507 507 # Dict holding all command-line options for each magic.
508 508 options_table = None
509 509 # Dict for the mapping of magic names to methods, set by class decorator
510 510 magics = None
511 511 # Flag to check that the class decorator was properly applied
512 512 registered = False
513 513 # Instance of IPython shell
514 514 shell = None
515 515
516 516 def __init__(self, shell):
517 517 if not(self.__class__.registered):
518 518 raise ValueError('Magics subclass without registration - '
519 519 'did you forget to apply @magics_class?')
520 520 self.shell = shell
521 521 self.options_table = {}
522 522 # The method decorators are run when the instance doesn't exist yet, so
523 523 # they can only record the names of the methods they are supposed to
524 524 # grab. Only now, that the instance exists, can we create the proper
525 525 # mapping to bound methods. So we read the info off the original names
526 526 # table and replace each method name by the actual bound method.
527 527 # But we mustn't clobber the *class* mapping, in case of multiple instances.
528 528 class_magics = self.magics
529 529 self.magics = {}
530 530 for mtype in magic_kinds:
531 531 tab = self.magics[mtype] = {}
532 532 cls_tab = class_magics[mtype]
533 533 for magic_name, meth_name in cls_tab.iteritems():
534 534 if isinstance(meth_name, basestring):
535 535 # it's a method name, grab it
536 536 tab[magic_name] = getattr(self, meth_name)
537 537 else:
538 538 # it's the real thing
539 539 tab[magic_name] = meth_name
540 540
541 541 def arg_err(self,func):
542 542 """Print docstring if incorrect arguments were passed"""
543 543 print 'Error in arguments:'
544 544 print oinspect.getdoc(func)
545 545
546 546 def format_latex(self, strng):
547 547 """Format a string for latex inclusion."""
548 548
549 549 # Characters that need to be escaped for latex:
550 550 escape_re = re.compile(r'(%|_|\$|#|&)',re.MULTILINE)
551 551 # Magic command names as headers:
552 552 cmd_name_re = re.compile(r'^(%s.*?):' % ESC_MAGIC,
553 553 re.MULTILINE)
554 554 # Magic commands
555 555 cmd_re = re.compile(r'(?P<cmd>%s.+?\b)(?!\}\}:)' % ESC_MAGIC,
556 556 re.MULTILINE)
557 557 # Paragraph continue
558 558 par_re = re.compile(r'\\$',re.MULTILINE)
559 559
560 560 # The "\n" symbol
561 561 newline_re = re.compile(r'\\n')
562 562
563 563 # Now build the string for output:
564 564 #strng = cmd_name_re.sub(r'\n\\texttt{\\textsl{\\large \1}}:',strng)
565 565 strng = cmd_name_re.sub(r'\n\\bigskip\n\\texttt{\\textbf{ \1}}:',
566 566 strng)
567 567 strng = cmd_re.sub(r'\\texttt{\g<cmd>}',strng)
568 568 strng = par_re.sub(r'\\\\',strng)
569 569 strng = escape_re.sub(r'\\\1',strng)
570 570 strng = newline_re.sub(r'\\textbackslash{}n',strng)
571 571 return strng
572 572
573 573 def parse_options(self, arg_str, opt_str, *long_opts, **kw):
574 574 """Parse options passed to an argument string.
575 575
576 576 The interface is similar to that of getopt(), but it returns back a
577 577 Struct with the options as keys and the stripped argument string still
578 578 as a string.
579 579
580 580 arg_str is quoted as a true sys.argv vector by using shlex.split.
581 581 This allows us to easily expand variables, glob files, quote
582 582 arguments, etc.
583 583
584 584 Options:
585 585 -mode: default 'string'. If given as 'list', the argument string is
586 586 returned as a list (split on whitespace) instead of a string.
587 587
588 588 -list_all: put all option values in lists. Normally only options
589 589 appearing more than once are put in a list.
590 590
591 591 -posix (True): whether to split the input line in POSIX mode or not,
592 592 as per the conventions outlined in the shlex module from the
593 593 standard library."""
594 594
595 595 # inject default options at the beginning of the input line
596 596 caller = sys._getframe(1).f_code.co_name
597 597 arg_str = '%s %s' % (self.options_table.get(caller,''),arg_str)
598 598
599 599 mode = kw.get('mode','string')
600 600 if mode not in ['string','list']:
601 601 raise ValueError('incorrect mode given: %s' % mode)
602 602 # Get options
603 603 list_all = kw.get('list_all',0)
604 604 posix = kw.get('posix', os.name == 'posix')
605 605 strict = kw.get('strict', True)
606 606
607 607 # Check if we have more than one argument to warrant extra processing:
608 608 odict = {} # Dictionary with options
609 609 args = arg_str.split()
610 610 if len(args) >= 1:
611 611 # If the list of inputs only has 0 or 1 thing in it, there's no
612 612 # need to look for options
613 613 argv = arg_split(arg_str, posix, strict)
614 614 # Do regular option processing
615 615 try:
616 616 opts,args = getopt(argv, opt_str, long_opts)
617 617 except GetoptError as e:
618 618 raise UsageError('%s ( allowed: "%s" %s)' % (e.msg,opt_str,
619 619 " ".join(long_opts)))
620 620 for o,a in opts:
621 621 if o.startswith('--'):
622 622 o = o[2:]
623 623 else:
624 624 o = o[1:]
625 625 try:
626 626 odict[o].append(a)
627 627 except AttributeError:
628 628 odict[o] = [odict[o],a]
629 629 except KeyError:
630 630 if list_all:
631 631 odict[o] = [a]
632 632 else:
633 633 odict[o] = a
634 634
635 635 # Prepare opts,args for return
636 636 opts = Struct(odict)
637 637 if mode == 'string':
638 638 args = ' '.join(args)
639 639
640 640 return opts,args
641 641
642 642 def default_option(self, fn, optstr):
643 643 """Make an entry in the options_table for fn, with value optstr"""
644 644
645 645 if fn not in self.lsmagic():
646 646 error("%s is not a magic function" % fn)
647 647 self.options_table[fn] = optstr
648 648
649 649 class MagicAlias(object):
650 650 """An alias to another magic function.
651 651
652 652 An alias is determined by its magic name and magic kind. Lookup
653 653 is done at call time, so if the underlying magic changes the alias
654 654 will call the new function.
655 655
656 656 Use the :meth:`MagicsManager.register_alias` method or the
657 657 `%alias_magic` magic function to create and register a new alias.
658 658 """
659 659 def __init__(self, shell, magic_name, magic_kind):
660 660 self.shell = shell
661 661 self.magic_name = magic_name
662 662 self.magic_kind = magic_kind
663 663
664 664 self.pretty_target = '%s%s' % (magic_escapes[self.magic_kind], self.magic_name)
665 665 self.__doc__ = "Alias for `%s`." % self.pretty_target
666 666
667 667 self._in_call = False
668 668
669 669 def __call__(self, *args, **kwargs):
670 670 """Call the magic alias."""
671 671 fn = self.shell.find_magic(self.magic_name, self.magic_kind)
672 672 if fn is None:
673 673 raise UsageError("Magic `%s` not found." % self.pretty_target)
674 674
675 675 # Protect against infinite recursion.
676 676 if self._in_call:
677 677 raise UsageError("Infinite recursion detected; "
678 678 "magic aliases cannot call themselves.")
679 679 self._in_call = True
680 680 try:
681 681 return fn(*args, **kwargs)
682 682 finally:
683 683 self._in_call = False
@@ -1,559 +1,558 b''
1 1 """Implementation of code management magic functions.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (c) 2012 The IPython Development Team.
5 5 #
6 6 # Distributed under the terms of the Modified BSD License.
7 7 #
8 8 # The full license is in the file COPYING.txt, distributed with this software.
9 9 #-----------------------------------------------------------------------------
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14
15 15 # Stdlib
16 16 import inspect
17 17 import io
18 18 import os
19 19 import re
20 20 import sys
21 21
22 22 # Our own packages
23 23 from IPython.core.error import TryNext, StdinNotImplementedError, UsageError
24 24 from IPython.core.macro import Macro
25 25 from IPython.core.magic import Magics, magics_class, line_magic
26 26 from IPython.core.oinspect import find_file, find_source_lines
27 27 from IPython.testing.skipdoctest import skip_doctest
28 from IPython.utils import openpy
29 28 from IPython.utils import py3compat
30 29 from IPython.utils.contexts import preserve_keys
31 30 from IPython.utils.io import file_read
32 31 from IPython.utils.path import get_py_filename, unquote_filename
33 32 from IPython.utils.warn import warn
34 33
35 34 #-----------------------------------------------------------------------------
36 35 # Magic implementation classes
37 36 #-----------------------------------------------------------------------------
38 37
39 38 # Used for exception handling in magic_edit
40 39 class MacroToEdit(ValueError): pass
41 40
42 41 ipython_input_pat = re.compile(r"<ipython\-input\-(\d+)-[a-z\d]+>$")
43 42
44 43 class InteractivelyDefined(Exception):
45 44 """Exception for interactively defined variable in magic_edit"""
46 45 def __init__(self, index):
47 46 self.index = index
48 47
49 48
50 49 @magics_class
51 50 class CodeMagics(Magics):
52 51 """Magics related to code management (loading, saving, editing, ...)."""
53 52
54 53 @line_magic
55 54 def save(self, parameter_s=''):
56 55 """Save a set of lines or a macro to a given filename.
57 56
58 57 Usage:\\
59 58 %save [options] filename n1-n2 n3-n4 ... n5 .. n6 ...
60 59
61 60 Options:
62 61
63 62 -r: use 'raw' input. By default, the 'processed' history is used,
64 63 so that magics are loaded in their transformed version to valid
65 64 Python. If this option is given, the raw input as typed as the
66 65 command line is used instead.
67 66
68 67 -f: force overwrite. If file exists, %save will prompt for overwrite
69 68 unless -f is given.
70 69
71 70 -a: append to the file instead of overwriting it.
72 71
73 72 This function uses the same syntax as %history for input ranges,
74 73 then saves the lines to the filename you specify.
75 74
76 75 It adds a '.py' extension to the file if you don't do so yourself, and
77 76 it asks for confirmation before overwriting existing files.
78 77
79 78 If `-r` option is used, the default extension is `.ipy`.
80 79 """
81 80
82 81 opts,args = self.parse_options(parameter_s,'fra',mode='list')
83 82 if not args:
84 83 raise UsageError('Missing filename.')
85 84 raw = 'r' in opts
86 85 force = 'f' in opts
87 86 append = 'a' in opts
88 87 mode = 'a' if append else 'w'
89 88 ext = u'.ipy' if raw else u'.py'
90 89 fname, codefrom = unquote_filename(args[0]), " ".join(args[1:])
91 90 if not fname.endswith((u'.py',u'.ipy')):
92 91 fname += ext
93 92 file_exists = os.path.isfile(fname)
94 93 if file_exists and not force and not append:
95 94 try:
96 95 overwrite = self.shell.ask_yes_no('File `%s` exists. Overwrite (y/[N])? ' % fname, default='n')
97 96 except StdinNotImplementedError:
98 97 print "File `%s` exists. Use `%%save -f %s` to force overwrite" % (fname, parameter_s)
99 98 return
100 99 if not overwrite :
101 100 print 'Operation cancelled.'
102 101 return
103 102 try:
104 103 cmds = self.shell.find_user_code(codefrom,raw)
105 104 except (TypeError, ValueError) as e:
106 105 print e.args[0]
107 106 return
108 107 out = py3compat.cast_unicode(cmds)
109 108 with io.open(fname, mode, encoding="utf-8") as f:
110 109 if not file_exists or not append:
111 110 f.write(u"# coding: utf-8\n")
112 111 f.write(out)
113 112 # make sure we end on a newline
114 113 if not out.endswith(u'\n'):
115 114 f.write(u'\n')
116 115 print 'The following commands were written to file `%s`:' % fname
117 116 print cmds
118 117
119 118 @line_magic
120 119 def pastebin(self, parameter_s=''):
121 120 """Upload code to Github's Gist paste bin, returning the URL.
122 121
123 122 Usage:\\
124 123 %pastebin [-d "Custom description"] 1-7
125 124
126 125 The argument can be an input history range, a filename, or the name of a
127 126 string or macro.
128 127
129 128 Options:
130 129
131 130 -d: Pass a custom description for the gist. The default will say
132 131 "Pasted from IPython".
133 132 """
134 133 opts, args = self.parse_options(parameter_s, 'd:')
135 134
136 135 try:
137 136 code = self.shell.find_user_code(args)
138 137 except (ValueError, TypeError) as e:
139 138 print e.args[0]
140 139 return
141 140
142 141 from urllib2 import urlopen # Deferred import
143 142 import json
144 143 post_data = json.dumps({
145 144 "description": opts.get('d', "Pasted from IPython"),
146 145 "public": True,
147 146 "files": {
148 147 "file1.py": {
149 148 "content": code
150 149 }
151 150 }
152 151 }).encode('utf-8')
153 152
154 153 response = urlopen("https://api.github.com/gists", post_data)
155 154 response_data = json.loads(response.read().decode('utf-8'))
156 155 return response_data['html_url']
157 156
158 157 @line_magic
159 158 def loadpy(self, arg_s):
160 159 """Alias of `%load`
161 160
162 161 `%loadpy` has gained some flexibility and droped the requirement of a `.py`
163 162 extension. So it has been renamed simply into %load. You can look at
164 163 `%load`'s docstring for more info.
165 164 """
166 165 self.load(arg_s)
167 166
168 167 @line_magic
169 168 def load(self, arg_s):
170 169 """Load code into the current frontend.
171 170
172 171 Usage:\\
173 172 %load [options] source
174 173
175 174 where source can be a filename, URL, input history range or macro
176 175
177 176 Options:
178 177 --------
179 178 -y : Don't ask confirmation for loading source above 200 000 characters.
180 179
181 180 This magic command can either take a local filename, a URL, an history
182 181 range (see %history) or a macro as argument, it will prompt for
183 182 confirmation before loading source with more than 200 000 characters, unless
184 183 -y flag is passed or if the frontend does not support raw_input::
185 184
186 185 %load myscript.py
187 186 %load 7-27
188 187 %load myMacro
189 188 %load http://www.example.com/myscript.py
190 189 """
191 190 opts,args = self.parse_options(arg_s,'y')
192 191 if not args:
193 192 raise UsageError('Missing filename, URL, input history range, '
194 193 'or macro.')
195 194
196 195 contents = self.shell.find_user_code(args)
197 196 l = len(contents)
198 197
199 198 # 200 000 is ~ 2500 full 80 caracter lines
200 199 # so in average, more than 5000 lines
201 200 if l > 200000 and 'y' not in opts:
202 201 try:
203 202 ans = self.shell.ask_yes_no(("The text you're trying to load seems pretty big"\
204 203 " (%d characters). Continue (y/[N]) ?" % l), default='n' )
205 204 except StdinNotImplementedError:
206 205 #asume yes if raw input not implemented
207 206 ans = True
208 207
209 208 if ans is False :
210 209 print 'Operation cancelled.'
211 210 return
212 211
213 212 self.shell.set_next_input(contents)
214 213
215 214 @staticmethod
216 215 def _find_edit_target(shell, args, opts, last_call):
217 216 """Utility method used by magic_edit to find what to edit."""
218 217
219 218 def make_filename(arg):
220 219 "Make a filename from the given args"
221 220 arg = unquote_filename(arg)
222 221 try:
223 222 filename = get_py_filename(arg)
224 223 except IOError:
225 224 # If it ends with .py but doesn't already exist, assume we want
226 225 # a new file.
227 226 if arg.endswith('.py'):
228 227 filename = arg
229 228 else:
230 229 filename = None
231 230 return filename
232 231
233 232 # Set a few locals from the options for convenience:
234 233 opts_prev = 'p' in opts
235 234 opts_raw = 'r' in opts
236 235
237 236 # custom exceptions
238 237 class DataIsObject(Exception): pass
239 238
240 239 # Default line number value
241 240 lineno = opts.get('n',None)
242 241
243 242 if opts_prev:
244 243 args = '_%s' % last_call[0]
245 244 if args not in shell.user_ns:
246 245 args = last_call[1]
247 246
248 247 # by default this is done with temp files, except when the given
249 248 # arg is a filename
250 249 use_temp = True
251 250
252 251 data = ''
253 252
254 253 # First, see if the arguments should be a filename.
255 254 filename = make_filename(args)
256 255 if filename:
257 256 use_temp = False
258 257 elif args:
259 258 # Mode where user specifies ranges of lines, like in %macro.
260 259 data = shell.extract_input_lines(args, opts_raw)
261 260 if not data:
262 261 try:
263 262 # Load the parameter given as a variable. If not a string,
264 263 # process it as an object instead (below)
265 264
266 265 #print '*** args',args,'type',type(args) # dbg
267 266 data = eval(args, shell.user_ns)
268 267 if not isinstance(data, basestring):
269 268 raise DataIsObject
270 269
271 270 except (NameError,SyntaxError):
272 271 # given argument is not a variable, try as a filename
273 272 filename = make_filename(args)
274 273 if filename is None:
275 274 warn("Argument given (%s) can't be found as a variable "
276 275 "or as a filename." % args)
277 276 return (None, None, None)
278 277 use_temp = False
279 278
280 279 except DataIsObject:
281 280 # macros have a special edit function
282 281 if isinstance(data, Macro):
283 282 raise MacroToEdit(data)
284 283
285 284 # For objects, try to edit the file where they are defined
286 285 filename = find_file(data)
287 286 if filename:
288 287 if 'fakemodule' in filename.lower() and \
289 288 inspect.isclass(data):
290 289 # class created by %edit? Try to find source
291 290 # by looking for method definitions instead, the
292 291 # __module__ in those classes is FakeModule.
293 292 attrs = [getattr(data, aname) for aname in dir(data)]
294 293 for attr in attrs:
295 294 if not inspect.ismethod(attr):
296 295 continue
297 296 filename = find_file(attr)
298 297 if filename and \
299 298 'fakemodule' not in filename.lower():
300 299 # change the attribute to be the edit
301 300 # target instead
302 301 data = attr
303 302 break
304 303
305 304 m = ipython_input_pat.match(os.path.basename(filename))
306 305 if m:
307 306 raise InteractivelyDefined(int(m.groups()[0]))
308 307
309 308 datafile = 1
310 309 if filename is None:
311 310 filename = make_filename(args)
312 311 datafile = 1
313 312 if filename is not None:
314 313 # only warn about this if we get a real name
315 314 warn('Could not find file where `%s` is defined.\n'
316 315 'Opening a file named `%s`' % (args, filename))
317 316 # Now, make sure we can actually read the source (if it was
318 317 # in a temp file it's gone by now).
319 318 if datafile:
320 319 if lineno is None:
321 320 lineno = find_source_lines(data)
322 321 if lineno is None:
323 322 filename = make_filename(args)
324 323 if filename is None:
325 324 warn('The file where `%s` was defined '
326 325 'cannot be read or found.' % data)
327 326 return (None, None, None)
328 327 use_temp = False
329 328
330 329 if use_temp:
331 330 filename = shell.mktempfile(data)
332 331 print 'IPython will make a temporary file named:',filename
333 332
334 333 # use last_call to remember the state of the previous call, but don't
335 334 # let it be clobbered by successive '-p' calls.
336 335 try:
337 336 last_call[0] = shell.displayhook.prompt_count
338 337 if not opts_prev:
339 338 last_call[1] = args
340 339 except:
341 340 pass
342 341
343 342
344 343 return filename, lineno, use_temp
345 344
346 345 def _edit_macro(self,mname,macro):
347 346 """open an editor with the macro data in a file"""
348 347 filename = self.shell.mktempfile(macro.value)
349 348 self.shell.hooks.editor(filename)
350 349
351 350 # and make a new macro object, to replace the old one
352 351 mfile = open(filename)
353 352 mvalue = mfile.read()
354 353 mfile.close()
355 354 self.shell.user_ns[mname] = Macro(mvalue)
356 355
357 356 @skip_doctest
358 357 @line_magic
359 358 def edit(self, parameter_s='',last_call=['','']):
360 359 """Bring up an editor and execute the resulting code.
361 360
362 361 Usage:
363 362 %edit [options] [args]
364 363
365 364 %edit runs IPython's editor hook. The default version of this hook is
366 365 set to call the editor specified by your $EDITOR environment variable.
367 366 If this isn't found, it will default to vi under Linux/Unix and to
368 367 notepad under Windows. See the end of this docstring for how to change
369 368 the editor hook.
370 369
371 370 You can also set the value of this editor via the
372 371 ``TerminalInteractiveShell.editor`` option in your configuration file.
373 372 This is useful if you wish to use a different editor from your typical
374 373 default with IPython (and for Windows users who typically don't set
375 374 environment variables).
376 375
377 376 This command allows you to conveniently edit multi-line code right in
378 377 your IPython session.
379 378
380 379 If called without arguments, %edit opens up an empty editor with a
381 380 temporary file and will execute the contents of this file when you
382 381 close it (don't forget to save it!).
383 382
384 383
385 384 Options:
386 385
387 386 -n <number>: open the editor at a specified line number. By default,
388 387 the IPython editor hook uses the unix syntax 'editor +N filename', but
389 388 you can configure this by providing your own modified hook if your
390 389 favorite editor supports line-number specifications with a different
391 390 syntax.
392 391
393 392 -p: this will call the editor with the same data as the previous time
394 393 it was used, regardless of how long ago (in your current session) it
395 394 was.
396 395
397 396 -r: use 'raw' input. This option only applies to input taken from the
398 397 user's history. By default, the 'processed' history is used, so that
399 398 magics are loaded in their transformed version to valid Python. If
400 399 this option is given, the raw input as typed as the command line is
401 400 used instead. When you exit the editor, it will be executed by
402 401 IPython's own processor.
403 402
404 403 -x: do not execute the edited code immediately upon exit. This is
405 404 mainly useful if you are editing programs which need to be called with
406 405 command line arguments, which you can then do using %run.
407 406
408 407
409 408 Arguments:
410 409
411 410 If arguments are given, the following possibilities exist:
412 411
413 412 - If the argument is a filename, IPython will load that into the
414 413 editor. It will execute its contents with execfile() when you exit,
415 414 loading any code in the file into your interactive namespace.
416 415
417 416 - The arguments are ranges of input history, e.g. "7 ~1/4-6".
418 417 The syntax is the same as in the %history magic.
419 418
420 419 - If the argument is a string variable, its contents are loaded
421 420 into the editor. You can thus edit any string which contains
422 421 python code (including the result of previous edits).
423 422
424 423 - If the argument is the name of an object (other than a string),
425 424 IPython will try to locate the file where it was defined and open the
426 425 editor at the point where it is defined. You can use `%edit function`
427 426 to load an editor exactly at the point where 'function' is defined,
428 427 edit it and have the file be executed automatically.
429 428
430 429 - If the object is a macro (see %macro for details), this opens up your
431 430 specified editor with a temporary file containing the macro's data.
432 431 Upon exit, the macro is reloaded with the contents of the file.
433 432
434 433 Note: opening at an exact line is only supported under Unix, and some
435 434 editors (like kedit and gedit up to Gnome 2.8) do not understand the
436 435 '+NUMBER' parameter necessary for this feature. Good editors like
437 436 (X)Emacs, vi, jed, pico and joe all do.
438 437
439 438 After executing your code, %edit will return as output the code you
440 439 typed in the editor (except when it was an existing file). This way
441 440 you can reload the code in further invocations of %edit as a variable,
442 441 via _<NUMBER> or Out[<NUMBER>], where <NUMBER> is the prompt number of
443 442 the output.
444 443
445 444 Note that %edit is also available through the alias %ed.
446 445
447 446 This is an example of creating a simple function inside the editor and
448 447 then modifying it. First, start up the editor::
449 448
450 449 In [1]: edit
451 450 Editing... done. Executing edited code...
452 451 Out[1]: 'def foo():\\n print "foo() was defined in an editing
453 452 session"\\n'
454 453
455 454 We can then call the function foo()::
456 455
457 456 In [2]: foo()
458 457 foo() was defined in an editing session
459 458
460 459 Now we edit foo. IPython automatically loads the editor with the
461 460 (temporary) file where foo() was previously defined::
462 461
463 462 In [3]: edit foo
464 463 Editing... done. Executing edited code...
465 464
466 465 And if we call foo() again we get the modified version::
467 466
468 467 In [4]: foo()
469 468 foo() has now been changed!
470 469
471 470 Here is an example of how to edit a code snippet successive
472 471 times. First we call the editor::
473 472
474 473 In [5]: edit
475 474 Editing... done. Executing edited code...
476 475 hello
477 476 Out[5]: "print 'hello'\\n"
478 477
479 478 Now we call it again with the previous output (stored in _)::
480 479
481 480 In [6]: edit _
482 481 Editing... done. Executing edited code...
483 482 hello world
484 483 Out[6]: "print 'hello world'\\n"
485 484
486 485 Now we call it with the output #8 (stored in _8, also as Out[8])::
487 486
488 487 In [7]: edit _8
489 488 Editing... done. Executing edited code...
490 489 hello again
491 490 Out[7]: "print 'hello again'\\n"
492 491
493 492
494 493 Changing the default editor hook:
495 494
496 495 If you wish to write your own editor hook, you can put it in a
497 496 configuration file which you load at startup time. The default hook
498 497 is defined in the IPython.core.hooks module, and you can use that as a
499 498 starting example for further modifications. That file also has
500 499 general instructions on how to set a new hook for use once you've
501 500 defined it."""
502 501 opts,args = self.parse_options(parameter_s,'prxn:')
503 502
504 503 try:
505 504 filename, lineno, is_temp = self._find_edit_target(self.shell,
506 505 args, opts, last_call)
507 506 except MacroToEdit as e:
508 507 self._edit_macro(args, e.args[0])
509 508 return
510 509 except InteractivelyDefined as e:
511 510 print "Editing In[%i]" % e.index
512 511 args = str(e.index)
513 512 filename, lineno, is_temp = self._find_edit_target(self.shell,
514 513 args, opts, last_call)
515 514 if filename is None:
516 515 # nothing was found, warnings have already been issued,
517 516 # just give up.
518 517 return
519 518
520 519 # do actual editing here
521 520 print 'Editing...',
522 521 sys.stdout.flush()
523 522 try:
524 523 # Quote filenames that may have spaces in them
525 524 if ' ' in filename:
526 525 filename = "'%s'" % filename
527 526 self.shell.hooks.editor(filename,lineno)
528 527 except TryNext:
529 528 warn('Could not open editor')
530 529 return
531 530
532 531 # XXX TODO: should this be generalized for all string vars?
533 532 # For now, this is special-cased to blocks created by cpaste
534 533 if args.strip() == 'pasted_block':
535 534 self.shell.user_ns['pasted_block'] = file_read(filename)
536 535
537 536 if 'x' in opts: # -x prevents actual execution
538 537 print
539 538 else:
540 539 print 'done. Executing edited code...'
541 540 with preserve_keys(self.shell.user_ns, '__file__'):
542 541 if not is_temp:
543 542 self.shell.user_ns['__file__'] = filename
544 543 if 'r' in opts: # Untranslated IPython code
545 544 self.shell.run_cell(file_read(filename),
546 545 store_history=False)
547 546 else:
548 547 self.shell.safe_execfile(filename, self.shell.user_ns,
549 548 self.shell.user_ns)
550 549
551 550 if is_temp:
552 551 try:
553 552 return open(filename).read()
554 553 except IOError as msg:
555 554 if msg.filename == filename:
556 555 warn('File not found. Did you forget to save?')
557 556 return
558 557 else:
559 558 self.shell.showtraceback()
@@ -1,47 +1,47 b''
1 1 """Simple magics for display formats"""
2 2 #-----------------------------------------------------------------------------
3 3 # Copyright (c) 2012 The IPython Development Team.
4 4 #
5 5 # Distributed under the terms of the Modified BSD License.
6 6 #
7 7 # The full license is in the file COPYING.txt, distributed with this software.
8 8 #-----------------------------------------------------------------------------
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Imports
12 12 #-----------------------------------------------------------------------------
13 13
14 14 # Our own packages
15 15 from IPython.core.display import display, Javascript, Latex, SVG
16 16 from IPython.core.magic import (
17 Magics, magics_class, line_magic, cell_magic
17 Magics, magics_class, cell_magic
18 18 )
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Magic implementation classes
22 22 #-----------------------------------------------------------------------------
23 23
24 24
25 25 @magics_class
26 26 class DisplayMagics(Magics):
27 27 """Magics for displaying various output types with literals
28 28
29 29 Defines javascript/latex cell magics for writing blocks in those languages,
30 30 to be rendered in the frontend.
31 31 """
32 32
33 33 @cell_magic
34 34 def javascript(self, line, cell):
35 35 """Run the cell block of Javascript code"""
36 36 display(Javascript(cell))
37 37
38 38
39 39 @cell_magic
40 40 def latex(self, line, cell):
41 41 """Render the cell as a block of latex"""
42 42 display(Latex(cell))
43 43
44 44 @cell_magic
45 45 def svg(self, line, cell):
46 46 """Render the cell as an SVG literal"""
47 47 display(SVG(cell))
@@ -1,319 +1,318 b''
1 1 """Implementation of magic functions related to History.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (c) 2012, IPython Development Team.
5 5 #
6 6 # Distributed under the terms of the Modified BSD License.
7 7 #
8 8 # The full license is in the file COPYING.txt, distributed with this software.
9 9 #-----------------------------------------------------------------------------
10 10
11 11 #-----------------------------------------------------------------------------
12 12 # Imports
13 13 #-----------------------------------------------------------------------------
14 14 from __future__ import print_function
15 15
16 16 # Stdlib
17 17 import os
18 18 from io import open as io_open
19 from IPython.external.argparse import Action
20 19
21 20 # Our own packages
22 21 from IPython.core.error import StdinNotImplementedError
23 22 from IPython.core.magic import Magics, magics_class, line_magic
24 23 from IPython.core.magic_arguments import (argument, magic_arguments,
25 24 parse_argstring)
26 25 from IPython.testing.skipdoctest import skip_doctest
27 26 from IPython.utils import io
28 27
29 28 #-----------------------------------------------------------------------------
30 29 # Magics class implementation
31 30 #-----------------------------------------------------------------------------
32 31
33 32
34 33 _unspecified = object()
35 34
36 35
37 36 @magics_class
38 37 class HistoryMagics(Magics):
39 38
40 39 @magic_arguments()
41 40 @argument(
42 41 '-n', dest='print_nums', action='store_true', default=False,
43 42 help="""
44 43 print line numbers for each input.
45 44 This feature is only available if numbered prompts are in use.
46 45 """)
47 46 @argument(
48 47 '-o', dest='get_output', action='store_true', default=False,
49 48 help="also print outputs for each input.")
50 49 @argument(
51 50 '-p', dest='pyprompts', action='store_true', default=False,
52 51 help="""
53 52 print classic '>>>' python prompts before each input.
54 53 This is useful for making documentation, and in conjunction
55 54 with -o, for producing doctest-ready output.
56 55 """)
57 56 @argument(
58 57 '-t', dest='raw', action='store_false', default=True,
59 58 help="""
60 59 print the 'translated' history, as IPython understands it.
61 60 IPython filters your input and converts it all into valid Python
62 61 source before executing it (things like magics or aliases are turned
63 62 into function calls, for example). With this option, you'll see the
64 63 native history instead of the user-entered version: '%%cd /' will be
65 64 seen as 'get_ipython().magic("%%cd /")' instead of '%%cd /'.
66 65 """)
67 66 @argument(
68 67 '-f', dest='filename',
69 68 help="""
70 69 FILENAME: instead of printing the output to the screen, redirect
71 70 it to the given file. The file is always overwritten, though *when
72 71 it can*, IPython asks for confirmation first. In particular, running
73 72 the command 'history -f FILENAME' from the IPython Notebook
74 73 interface will replace FILENAME even if it already exists *without*
75 74 confirmation.
76 75 """)
77 76 @argument(
78 77 '-g', dest='pattern', nargs='*', default=None,
79 78 help="""
80 79 treat the arg as a glob pattern to search for in (full) history.
81 80 This includes the saved history (almost all commands ever written).
82 81 The pattern may contain '?' to match one unknown character and '*'
83 82 to match any number of unknown characters. Use '%%hist -g' to show
84 83 full saved history (may be very long).
85 84 """)
86 85 @argument(
87 86 '-l', dest='limit', type=int, nargs='?', default=_unspecified,
88 87 help="""
89 88 get the last n lines from all sessions. Specify n as a single
90 89 arg, or the default is the last 10 lines.
91 90 """)
92 91 @argument(
93 92 '-u', dest='unique', action='store_true',
94 93 help="""
95 94 when searching history using `-g`, show only unique history.
96 95 """)
97 96 @argument('range', nargs='*')
98 97 @skip_doctest
99 98 @line_magic
100 99 def history(self, parameter_s = ''):
101 100 """Print input history (_i<n> variables), with most recent last.
102 101
103 102 By default, input history is printed without line numbers so it can be
104 103 directly pasted into an editor. Use -n to show them.
105 104
106 105 By default, all input history from the current session is displayed.
107 106 Ranges of history can be indicated using the syntax:
108 107
109 108 ``4``
110 109 Line 4, current session
111 110 ``4-6``
112 111 Lines 4-6, current session
113 112 ``243/1-5``
114 113 Lines 1-5, session 243
115 114 ``~2/7``
116 115 Line 7, session 2 before current
117 116 ``~8/1-~6/5``
118 117 From the first line of 8 sessions ago, to the fifth line of 6
119 118 sessions ago.
120 119
121 120 Multiple ranges can be entered, separated by spaces
122 121
123 122 The same syntax is used by %macro, %save, %edit, %rerun
124 123
125 124 Examples
126 125 --------
127 126 ::
128 127
129 128 In [6]: %history -n 4-6
130 129 4:a = 12
131 130 5:print a**2
132 131 6:%history -n 4-6
133 132
134 133 """
135 134
136 135 args = parse_argstring(self.history, parameter_s)
137 136
138 137 # For brevity
139 138 history_manager = self.shell.history_manager
140 139
141 140 def _format_lineno(session, line):
142 141 """Helper function to format line numbers properly."""
143 142 if session in (0, history_manager.session_number):
144 143 return str(line)
145 144 return "%s/%s" % (session, line)
146 145
147 146 # Check if output to specific file was requested.
148 147 outfname = args.filename
149 148 if not outfname:
150 149 outfile = io.stdout # default
151 150 # We don't want to close stdout at the end!
152 151 close_at_end = False
153 152 else:
154 153 if os.path.exists(outfname):
155 154 try:
156 155 ans = io.ask_yes_no("File %r exists. Overwrite?" % outfname)
157 156 except StdinNotImplementedError:
158 157 ans = True
159 158 if not ans:
160 159 print('Aborting.')
161 160 return
162 161 print("Overwriting file.")
163 162 outfile = io_open(outfname, 'w', encoding='utf-8')
164 163 close_at_end = True
165 164
166 165 print_nums = args.print_nums
167 166 get_output = args.get_output
168 167 pyprompts = args.pyprompts
169 168 raw = args.raw
170 169
171 170 pattern = None
172 171 limit = None if args.limit is _unspecified else args.limit
173 172
174 173 if args.pattern is not None:
175 174 if args.pattern:
176 175 pattern = "*" + " ".join(args.pattern) + "*"
177 176 else:
178 177 pattern = "*"
179 178 hist = history_manager.search(pattern, raw=raw, output=get_output,
180 179 n=limit, unique=args.unique)
181 180 print_nums = True
182 181 elif args.limit is not _unspecified:
183 182 n = 10 if limit is None else limit
184 183 hist = history_manager.get_tail(n, raw=raw, output=get_output)
185 184 else:
186 185 if args.range: # Get history by ranges
187 186 hist = history_manager.get_range_by_str(" ".join(args.range),
188 187 raw, get_output)
189 188 else: # Just get history for the current session
190 189 hist = history_manager.get_range(raw=raw, output=get_output)
191 190
192 191 # We could be displaying the entire history, so let's not try to pull
193 192 # it into a list in memory. Anything that needs more space will just
194 193 # misalign.
195 194 width = 4
196 195
197 196 for session, lineno, inline in hist:
198 197 # Print user history with tabs expanded to 4 spaces. The GUI
199 198 # clients use hard tabs for easier usability in auto-indented code,
200 199 # but we want to produce PEP-8 compliant history for safe pasting
201 200 # into an editor.
202 201 if get_output:
203 202 inline, output = inline
204 203 inline = inline.expandtabs(4).rstrip()
205 204
206 205 multiline = "\n" in inline
207 206 line_sep = '\n' if multiline else ' '
208 207 if print_nums:
209 208 print(u'%s:%s' % (_format_lineno(session, lineno).rjust(width),
210 209 line_sep), file=outfile, end=u'')
211 210 if pyprompts:
212 211 print(u">>> ", end=u"", file=outfile)
213 212 if multiline:
214 213 inline = "\n... ".join(inline.splitlines()) + "\n..."
215 214 print(inline, file=outfile)
216 215 if get_output and output:
217 216 print(output, file=outfile)
218 217
219 218 if close_at_end:
220 219 outfile.close()
221 220
222 221 @line_magic
223 222 def recall(self, arg):
224 223 r"""Repeat a command, or get command to input line for editing.
225 224
226 225 %recall and %rep are equivalent.
227 226
228 227 - %recall (no arguments):
229 228
230 229 Place a string version of last computation result (stored in the
231 230 special '_' variable) to the next input prompt. Allows you to create
232 231 elaborate command lines without using copy-paste::
233 232
234 233 In[1]: l = ["hei", "vaan"]
235 234 In[2]: "".join(l)
236 235 Out[2]: heivaan
237 236 In[3]: %recall
238 237 In[4]: heivaan_ <== cursor blinking
239 238
240 239 %recall 45
241 240
242 241 Place history line 45 on the next input prompt. Use %hist to find
243 242 out the number.
244 243
245 244 %recall 1-4
246 245
247 246 Combine the specified lines into one cell, and place it on the next
248 247 input prompt. See %history for the slice syntax.
249 248
250 249 %recall foo+bar
251 250
252 251 If foo+bar can be evaluated in the user namespace, the result is
253 252 placed at the next input prompt. Otherwise, the history is searched
254 253 for lines which contain that substring, and the most recent one is
255 254 placed at the next input prompt.
256 255 """
257 256 if not arg: # Last output
258 257 self.shell.set_next_input(str(self.shell.user_ns["_"]))
259 258 return
260 259 # Get history range
261 260 histlines = self.shell.history_manager.get_range_by_str(arg)
262 261 cmd = "\n".join(x[2] for x in histlines)
263 262 if cmd:
264 263 self.shell.set_next_input(cmd.rstrip())
265 264 return
266 265
267 266 try: # Variable in user namespace
268 267 cmd = str(eval(arg, self.shell.user_ns))
269 268 except Exception: # Search for term in history
270 269 histlines = self.shell.history_manager.search("*"+arg+"*")
271 270 for h in reversed([x[2] for x in histlines]):
272 271 if 'recall' in h or 'rep' in h:
273 272 continue
274 273 self.shell.set_next_input(h.rstrip())
275 274 return
276 275 else:
277 276 self.shell.set_next_input(cmd.rstrip())
278 277 print("Couldn't evaluate or find in history:", arg)
279 278
280 279 @line_magic
281 280 def rerun(self, parameter_s=''):
282 281 """Re-run previous input
283 282
284 283 By default, you can specify ranges of input history to be repeated
285 284 (as with %history). With no arguments, it will repeat the last line.
286 285
287 286 Options:
288 287
289 288 -l <n> : Repeat the last n lines of input, not including the
290 289 current command.
291 290
292 291 -g foo : Repeat the most recent line which contains foo
293 292 """
294 293 opts, args = self.parse_options(parameter_s, 'l:g:', mode='string')
295 294 if "l" in opts: # Last n lines
296 295 n = int(opts['l'])
297 296 hist = self.shell.history_manager.get_tail(n)
298 297 elif "g" in opts: # Search
299 298 p = "*"+opts['g']+"*"
300 299 hist = list(self.shell.history_manager.search(p))
301 300 for l in reversed(hist):
302 301 if "rerun" not in l[2]:
303 302 hist = [l] # The last match which isn't a %rerun
304 303 break
305 304 else:
306 305 hist = [] # No matches except %rerun
307 306 elif args: # Specify history ranges
308 307 hist = self.shell.history_manager.get_range_by_str(args)
309 308 else: # Last line
310 309 hist = self.shell.history_manager.get_tail(1)
311 310 hist = [x[2] for x in hist]
312 311 if not hist:
313 312 print("No lines in history match specification")
314 313 return
315 314 histlines = "\n".join(hist)
316 315 print("=== Executing: ===")
317 316 print(histlines)
318 317 print("=== Output: ===")
319 318 self.shell.run_cell("\n".join(hist), store_history=False)
@@ -1,725 +1,725 b''
1 1 """Implementation of magic functions for interaction with the OS.
2 2
3 3 Note: this module is named 'osm' instead of 'os' to avoid a collision with the
4 4 builtin.
5 5 """
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (c) 2012 The IPython Development Team.
8 8 #
9 9 # Distributed under the terms of the Modified BSD License.
10 10 #
11 11 # The full license is in the file COPYING.txt, distributed with this software.
12 12 #-----------------------------------------------------------------------------
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Imports
16 16 #-----------------------------------------------------------------------------
17 17
18 18 # Stdlib
19 19 import io
20 20 import os
21 21 import re
22 22 import sys
23 23 from pprint import pformat
24 24
25 25 # Our own packages
26 26 from IPython.core import magic_arguments
27 27 from IPython.core import oinspect
28 28 from IPython.core import page
29 from IPython.core.error import UsageError, StdinNotImplementedError
29 from IPython.core.error import UsageError
30 30 from IPython.core.magic import (
31 31 Magics, compress_dhist, magics_class, line_magic, cell_magic, line_cell_magic
32 32 )
33 33 from IPython.testing.skipdoctest import skip_doctest
34 from IPython.utils.io import file_read, nlprint
34 from IPython.utils.io import nlprint
35 35 from IPython.utils.openpy import source_to_unicode
36 from IPython.utils.path import get_py_filename, unquote_filename
36 from IPython.utils.path import unquote_filename
37 37 from IPython.utils.process import abbrev_cwd
38 38 from IPython.utils.terminal import set_term_title
39 39 #-----------------------------------------------------------------------------
40 40 # Magic implementation classes
41 41 #-----------------------------------------------------------------------------
42 42 @magics_class
43 43 class OSMagics(Magics):
44 44 """Magics to interact with the underlying OS (shell-type functionality).
45 45 """
46 46
47 47 @skip_doctest
48 48 @line_magic
49 49 def alias(self, parameter_s=''):
50 50 """Define an alias for a system command.
51 51
52 52 '%alias alias_name cmd' defines 'alias_name' as an alias for 'cmd'
53 53
54 54 Then, typing 'alias_name params' will execute the system command 'cmd
55 55 params' (from your underlying operating system).
56 56
57 57 Aliases have lower precedence than magic functions and Python normal
58 58 variables, so if 'foo' is both a Python variable and an alias, the
59 59 alias can not be executed until 'del foo' removes the Python variable.
60 60
61 61 You can use the %l specifier in an alias definition to represent the
62 62 whole line when the alias is called. For example::
63 63
64 64 In [2]: alias bracket echo "Input in brackets: <%l>"
65 65 In [3]: bracket hello world
66 66 Input in brackets: <hello world>
67 67
68 68 You can also define aliases with parameters using %s specifiers (one
69 69 per parameter)::
70 70
71 71 In [1]: alias parts echo first %s second %s
72 72 In [2]: %parts A B
73 73 first A second B
74 74 In [3]: %parts A
75 75 Incorrect number of arguments: 2 expected.
76 76 parts is an alias to: 'echo first %s second %s'
77 77
78 78 Note that %l and %s are mutually exclusive. You can only use one or
79 79 the other in your aliases.
80 80
81 81 Aliases expand Python variables just like system calls using ! or !!
82 82 do: all expressions prefixed with '$' get expanded. For details of
83 83 the semantic rules, see PEP-215:
84 84 http://www.python.org/peps/pep-0215.html. This is the library used by
85 85 IPython for variable expansion. If you want to access a true shell
86 86 variable, an extra $ is necessary to prevent its expansion by
87 87 IPython::
88 88
89 89 In [6]: alias show echo
90 90 In [7]: PATH='A Python string'
91 91 In [8]: show $PATH
92 92 A Python string
93 93 In [9]: show $$PATH
94 94 /usr/local/lf9560/bin:/usr/local/intel/compiler70/ia32/bin:...
95 95
96 96 You can use the alias facility to acess all of $PATH. See the %rehash
97 97 and %rehashx functions, which automatically create aliases for the
98 98 contents of your $PATH.
99 99
100 100 If called with no parameters, %alias prints the current alias table."""
101 101
102 102 par = parameter_s.strip()
103 103 if not par:
104 104 aliases = sorted(self.shell.alias_manager.aliases)
105 105 # stored = self.shell.db.get('stored_aliases', {} )
106 106 # for k, v in stored:
107 107 # atab.append(k, v[0])
108 108
109 109 print "Total number of aliases:", len(aliases)
110 110 sys.stdout.flush()
111 111 return aliases
112 112
113 113 # Now try to define a new one
114 114 try:
115 115 alias,cmd = par.split(None, 1)
116 116 except:
117 117 print oinspect.getdoc(self.alias)
118 118 else:
119 119 self.shell.alias_manager.soft_define_alias(alias, cmd)
120 120 # end magic_alias
121 121
122 122 @line_magic
123 123 def unalias(self, parameter_s=''):
124 124 """Remove an alias"""
125 125
126 126 aname = parameter_s.strip()
127 127 self.shell.alias_manager.undefine_alias(aname)
128 128 stored = self.shell.db.get('stored_aliases', {} )
129 129 if aname in stored:
130 130 print "Removing %stored alias",aname
131 131 del stored[aname]
132 132 self.shell.db['stored_aliases'] = stored
133 133
134 134 @line_magic
135 135 def rehashx(self, parameter_s=''):
136 136 """Update the alias table with all executable files in $PATH.
137 137
138 138 This version explicitly checks that every entry in $PATH is a file
139 139 with execute access (os.X_OK), so it is much slower than %rehash.
140 140
141 141 Under Windows, it checks executability as a match against a
142 142 '|'-separated string of extensions, stored in the IPython config
143 143 variable win_exec_ext. This defaults to 'exe|com|bat'.
144 144
145 145 This function also resets the root module cache of module completer,
146 146 used on slow filesystems.
147 147 """
148 148 from IPython.core.alias import InvalidAliasError
149 149
150 150 # for the benefit of module completer in ipy_completers.py
151 151 del self.shell.db['rootmodules']
152 152
153 153 path = [os.path.abspath(os.path.expanduser(p)) for p in
154 154 os.environ.get('PATH','').split(os.pathsep)]
155 155 path = filter(os.path.isdir,path)
156 156
157 157 syscmdlist = []
158 158 # Now define isexec in a cross platform manner.
159 159 if os.name == 'posix':
160 160 isexec = lambda fname:os.path.isfile(fname) and \
161 161 os.access(fname,os.X_OK)
162 162 else:
163 163 try:
164 164 winext = os.environ['pathext'].replace(';','|').replace('.','')
165 165 except KeyError:
166 166 winext = 'exe|com|bat|py'
167 167 if 'py' not in winext:
168 168 winext += '|py'
169 169 execre = re.compile(r'(.*)\.(%s)$' % winext,re.IGNORECASE)
170 170 isexec = lambda fname:os.path.isfile(fname) and execre.match(fname)
171 171 savedir = os.getcwdu()
172 172
173 173 # Now walk the paths looking for executables to alias.
174 174 try:
175 175 # write the whole loop for posix/Windows so we don't have an if in
176 176 # the innermost part
177 177 if os.name == 'posix':
178 178 for pdir in path:
179 179 os.chdir(pdir)
180 180 for ff in os.listdir(pdir):
181 181 if isexec(ff):
182 182 try:
183 183 # Removes dots from the name since ipython
184 184 # will assume names with dots to be python.
185 185 self.shell.alias_manager.define_alias(
186 186 ff.replace('.',''), ff)
187 187 except InvalidAliasError:
188 188 pass
189 189 else:
190 190 syscmdlist.append(ff)
191 191 else:
192 192 no_alias = self.shell.alias_manager.no_alias
193 193 for pdir in path:
194 194 os.chdir(pdir)
195 195 for ff in os.listdir(pdir):
196 196 base, ext = os.path.splitext(ff)
197 197 if isexec(ff) and base.lower() not in no_alias:
198 198 if ext.lower() == '.exe':
199 199 ff = base
200 200 try:
201 201 # Removes dots from the name since ipython
202 202 # will assume names with dots to be python.
203 203 self.shell.alias_manager.define_alias(
204 204 base.lower().replace('.',''), ff)
205 205 except InvalidAliasError:
206 206 pass
207 207 syscmdlist.append(ff)
208 208 self.shell.db['syscmdlist'] = syscmdlist
209 209 finally:
210 210 os.chdir(savedir)
211 211
212 212 @skip_doctest
213 213 @line_magic
214 214 def pwd(self, parameter_s=''):
215 215 """Return the current working directory path.
216 216
217 217 Examples
218 218 --------
219 219 ::
220 220
221 221 In [9]: pwd
222 222 Out[9]: '/home/tsuser/sprint/ipython'
223 223 """
224 224 return os.getcwdu()
225 225
226 226 @skip_doctest
227 227 @line_magic
228 228 def cd(self, parameter_s=''):
229 229 """Change the current working directory.
230 230
231 231 This command automatically maintains an internal list of directories
232 232 you visit during your IPython session, in the variable _dh. The
233 233 command %dhist shows this history nicely formatted. You can also
234 234 do 'cd -<tab>' to see directory history conveniently.
235 235
236 236 Usage:
237 237
238 238 cd 'dir': changes to directory 'dir'.
239 239
240 240 cd -: changes to the last visited directory.
241 241
242 242 cd -<n>: changes to the n-th directory in the directory history.
243 243
244 244 cd --foo: change to directory that matches 'foo' in history
245 245
246 246 cd -b <bookmark_name>: jump to a bookmark set by %bookmark
247 247 (note: cd <bookmark_name> is enough if there is no
248 248 directory <bookmark_name>, but a bookmark with the name exists.)
249 249 'cd -b <tab>' allows you to tab-complete bookmark names.
250 250
251 251 Options:
252 252
253 253 -q: quiet. Do not print the working directory after the cd command is
254 254 executed. By default IPython's cd command does print this directory,
255 255 since the default prompts do not display path information.
256 256
257 257 Note that !cd doesn't work for this purpose because the shell where
258 258 !command runs is immediately discarded after executing 'command'.
259 259
260 260 Examples
261 261 --------
262 262 ::
263 263
264 264 In [10]: cd parent/child
265 265 /home/tsuser/parent/child
266 266 """
267 267
268 268 oldcwd = os.getcwdu()
269 269 numcd = re.match(r'(-)(\d+)$',parameter_s)
270 270 # jump in directory history by number
271 271 if numcd:
272 272 nn = int(numcd.group(2))
273 273 try:
274 274 ps = self.shell.user_ns['_dh'][nn]
275 275 except IndexError:
276 276 print 'The requested directory does not exist in history.'
277 277 return
278 278 else:
279 279 opts = {}
280 280 elif parameter_s.startswith('--'):
281 281 ps = None
282 282 fallback = None
283 283 pat = parameter_s[2:]
284 284 dh = self.shell.user_ns['_dh']
285 285 # first search only by basename (last component)
286 286 for ent in reversed(dh):
287 287 if pat in os.path.basename(ent) and os.path.isdir(ent):
288 288 ps = ent
289 289 break
290 290
291 291 if fallback is None and pat in ent and os.path.isdir(ent):
292 292 fallback = ent
293 293
294 294 # if we have no last part match, pick the first full path match
295 295 if ps is None:
296 296 ps = fallback
297 297
298 298 if ps is None:
299 299 print "No matching entry in directory history"
300 300 return
301 301 else:
302 302 opts = {}
303 303
304 304
305 305 else:
306 306 #turn all non-space-escaping backslashes to slashes,
307 307 # for c:\windows\directory\names\
308 308 parameter_s = re.sub(r'\\(?! )','/', parameter_s)
309 309 opts,ps = self.parse_options(parameter_s,'qb',mode='string')
310 310 # jump to previous
311 311 if ps == '-':
312 312 try:
313 313 ps = self.shell.user_ns['_dh'][-2]
314 314 except IndexError:
315 315 raise UsageError('%cd -: No previous directory to change to.')
316 316 # jump to bookmark if needed
317 317 else:
318 318 if not os.path.isdir(ps) or 'b' in opts:
319 319 bkms = self.shell.db.get('bookmarks', {})
320 320
321 321 if ps in bkms:
322 322 target = bkms[ps]
323 323 print '(bookmark:%s) -> %s' % (ps, target)
324 324 ps = target
325 325 else:
326 326 if 'b' in opts:
327 327 raise UsageError("Bookmark '%s' not found. "
328 328 "Use '%%bookmark -l' to see your bookmarks." % ps)
329 329
330 330 # strip extra quotes on Windows, because os.chdir doesn't like them
331 331 ps = unquote_filename(ps)
332 332 # at this point ps should point to the target dir
333 333 if ps:
334 334 try:
335 335 os.chdir(os.path.expanduser(ps))
336 336 if hasattr(self.shell, 'term_title') and self.shell.term_title:
337 337 set_term_title('IPython: ' + abbrev_cwd())
338 338 except OSError:
339 339 print sys.exc_info()[1]
340 340 else:
341 341 cwd = os.getcwdu()
342 342 dhist = self.shell.user_ns['_dh']
343 343 if oldcwd != cwd:
344 344 dhist.append(cwd)
345 345 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
346 346
347 347 else:
348 348 os.chdir(self.shell.home_dir)
349 349 if hasattr(self.shell, 'term_title') and self.shell.term_title:
350 350 set_term_title('IPython: ' + '~')
351 351 cwd = os.getcwdu()
352 352 dhist = self.shell.user_ns['_dh']
353 353
354 354 if oldcwd != cwd:
355 355 dhist.append(cwd)
356 356 self.shell.db['dhist'] = compress_dhist(dhist)[-100:]
357 357 if not 'q' in opts and self.shell.user_ns['_dh']:
358 358 print self.shell.user_ns['_dh'][-1]
359 359
360 360
361 361 @line_magic
362 362 def env(self, parameter_s=''):
363 363 """List environment variables."""
364 364
365 365 return dict(os.environ)
366 366
367 367 @line_magic
368 368 def pushd(self, parameter_s=''):
369 369 """Place the current dir on stack and change directory.
370 370
371 371 Usage:\\
372 372 %pushd ['dirname']
373 373 """
374 374
375 375 dir_s = self.shell.dir_stack
376 376 tgt = os.path.expanduser(unquote_filename(parameter_s))
377 377 cwd = os.getcwdu().replace(self.shell.home_dir,'~')
378 378 if tgt:
379 379 self.cd(parameter_s)
380 380 dir_s.insert(0,cwd)
381 381 return self.shell.magic('dirs')
382 382
383 383 @line_magic
384 384 def popd(self, parameter_s=''):
385 385 """Change to directory popped off the top of the stack.
386 386 """
387 387 if not self.shell.dir_stack:
388 388 raise UsageError("%popd on empty stack")
389 389 top = self.shell.dir_stack.pop(0)
390 390 self.cd(top)
391 391 print "popd ->",top
392 392
393 393 @line_magic
394 394 def dirs(self, parameter_s=''):
395 395 """Return the current directory stack."""
396 396
397 397 return self.shell.dir_stack
398 398
399 399 @line_magic
400 400 def dhist(self, parameter_s=''):
401 401 """Print your history of visited directories.
402 402
403 403 %dhist -> print full history\\
404 404 %dhist n -> print last n entries only\\
405 405 %dhist n1 n2 -> print entries between n1 and n2 (n1 not included)\\
406 406
407 407 This history is automatically maintained by the %cd command, and
408 408 always available as the global list variable _dh. You can use %cd -<n>
409 409 to go to directory number <n>.
410 410
411 411 Note that most of time, you should view directory history by entering
412 412 cd -<TAB>.
413 413
414 414 """
415 415
416 416 dh = self.shell.user_ns['_dh']
417 417 if parameter_s:
418 418 try:
419 419 args = map(int,parameter_s.split())
420 420 except:
421 421 self.arg_err(self.dhist)
422 422 return
423 423 if len(args) == 1:
424 424 ini,fin = max(len(dh)-(args[0]),0),len(dh)
425 425 elif len(args) == 2:
426 426 ini,fin = args
427 427 else:
428 428 self.arg_err(self.dhist)
429 429 return
430 430 else:
431 431 ini,fin = 0,len(dh)
432 432 nlprint(dh,
433 433 header = 'Directory history (kept in _dh)',
434 434 start=ini,stop=fin)
435 435
436 436 @skip_doctest
437 437 @line_magic
438 438 def sc(self, parameter_s=''):
439 439 """Shell capture - run shell command and capture output (DEPRECATED use !).
440 440
441 441 DEPRECATED. Suboptimal, retained for backwards compatibility.
442 442
443 443 You should use the form 'var = !command' instead. Example:
444 444
445 445 "%sc -l myfiles = ls ~" should now be written as
446 446
447 447 "myfiles = !ls ~"
448 448
449 449 myfiles.s, myfiles.l and myfiles.n still apply as documented
450 450 below.
451 451
452 452 --
453 453 %sc [options] varname=command
454 454
455 455 IPython will run the given command using commands.getoutput(), and
456 456 will then update the user's interactive namespace with a variable
457 457 called varname, containing the value of the call. Your command can
458 458 contain shell wildcards, pipes, etc.
459 459
460 460 The '=' sign in the syntax is mandatory, and the variable name you
461 461 supply must follow Python's standard conventions for valid names.
462 462
463 463 (A special format without variable name exists for internal use)
464 464
465 465 Options:
466 466
467 467 -l: list output. Split the output on newlines into a list before
468 468 assigning it to the given variable. By default the output is stored
469 469 as a single string.
470 470
471 471 -v: verbose. Print the contents of the variable.
472 472
473 473 In most cases you should not need to split as a list, because the
474 474 returned value is a special type of string which can automatically
475 475 provide its contents either as a list (split on newlines) or as a
476 476 space-separated string. These are convenient, respectively, either
477 477 for sequential processing or to be passed to a shell command.
478 478
479 479 For example::
480 480
481 481 # Capture into variable a
482 482 In [1]: sc a=ls *py
483 483
484 484 # a is a string with embedded newlines
485 485 In [2]: a
486 486 Out[2]: 'setup.py\\nwin32_manual_post_install.py'
487 487
488 488 # which can be seen as a list:
489 489 In [3]: a.l
490 490 Out[3]: ['setup.py', 'win32_manual_post_install.py']
491 491
492 492 # or as a whitespace-separated string:
493 493 In [4]: a.s
494 494 Out[4]: 'setup.py win32_manual_post_install.py'
495 495
496 496 # a.s is useful to pass as a single command line:
497 497 In [5]: !wc -l $a.s
498 498 146 setup.py
499 499 130 win32_manual_post_install.py
500 500 276 total
501 501
502 502 # while the list form is useful to loop over:
503 503 In [6]: for f in a.l:
504 504 ...: !wc -l $f
505 505 ...:
506 506 146 setup.py
507 507 130 win32_manual_post_install.py
508 508
509 509 Similarly, the lists returned by the -l option are also special, in
510 510 the sense that you can equally invoke the .s attribute on them to
511 511 automatically get a whitespace-separated string from their contents::
512 512
513 513 In [7]: sc -l b=ls *py
514 514
515 515 In [8]: b
516 516 Out[8]: ['setup.py', 'win32_manual_post_install.py']
517 517
518 518 In [9]: b.s
519 519 Out[9]: 'setup.py win32_manual_post_install.py'
520 520
521 521 In summary, both the lists and strings used for output capture have
522 522 the following special attributes::
523 523
524 524 .l (or .list) : value as list.
525 525 .n (or .nlstr): value as newline-separated string.
526 526 .s (or .spstr): value as space-separated string.
527 527 """
528 528
529 529 opts,args = self.parse_options(parameter_s, 'lv')
530 530 # Try to get a variable name and command to run
531 531 try:
532 532 # the variable name must be obtained from the parse_options
533 533 # output, which uses shlex.split to strip options out.
534 534 var,_ = args.split('=', 1)
535 535 var = var.strip()
536 536 # But the command has to be extracted from the original input
537 537 # parameter_s, not on what parse_options returns, to avoid the
538 538 # quote stripping which shlex.split performs on it.
539 539 _,cmd = parameter_s.split('=', 1)
540 540 except ValueError:
541 541 var,cmd = '',''
542 542 # If all looks ok, proceed
543 543 split = 'l' in opts
544 544 out = self.shell.getoutput(cmd, split=split)
545 545 if 'v' in opts:
546 546 print '%s ==\n%s' % (var, pformat(out))
547 547 if var:
548 548 self.shell.user_ns.update({var:out})
549 549 else:
550 550 return out
551 551
552 552 @line_cell_magic
553 553 def sx(self, line='', cell=None):
554 554 """Shell execute - run shell command and capture output (!! is short-hand).
555 555
556 556 %sx command
557 557
558 558 IPython will run the given command using commands.getoutput(), and
559 559 return the result formatted as a list (split on '\\n'). Since the
560 560 output is _returned_, it will be stored in ipython's regular output
561 561 cache Out[N] and in the '_N' automatic variables.
562 562
563 563 Notes:
564 564
565 565 1) If an input line begins with '!!', then %sx is automatically
566 566 invoked. That is, while::
567 567
568 568 !ls
569 569
570 570 causes ipython to simply issue system('ls'), typing::
571 571
572 572 !!ls
573 573
574 574 is a shorthand equivalent to::
575 575
576 576 %sx ls
577 577
578 578 2) %sx differs from %sc in that %sx automatically splits into a list,
579 579 like '%sc -l'. The reason for this is to make it as easy as possible
580 580 to process line-oriented shell output via further python commands.
581 581 %sc is meant to provide much finer control, but requires more
582 582 typing.
583 583
584 584 3) Just like %sc -l, this is a list with special attributes:
585 585 ::
586 586
587 587 .l (or .list) : value as list.
588 588 .n (or .nlstr): value as newline-separated string.
589 589 .s (or .spstr): value as whitespace-separated string.
590 590
591 591 This is very useful when trying to use such lists as arguments to
592 592 system commands."""
593 593
594 594 if cell is None:
595 595 # line magic
596 596 return self.shell.getoutput(line)
597 597 else:
598 598 opts,args = self.parse_options(line, '', 'out=')
599 599 output = self.shell.getoutput(cell)
600 600 out_name = opts.get('out', opts.get('o'))
601 601 if out_name:
602 602 self.shell.user_ns[out_name] = output
603 603 else:
604 604 return output
605 605
606 606 system = line_cell_magic('system')(sx)
607 607 bang = cell_magic('!')(sx)
608 608
609 609 @line_magic
610 610 def bookmark(self, parameter_s=''):
611 611 """Manage IPython's bookmark system.
612 612
613 613 %bookmark <name> - set bookmark to current dir
614 614 %bookmark <name> <dir> - set bookmark to <dir>
615 615 %bookmark -l - list all bookmarks
616 616 %bookmark -d <name> - remove bookmark
617 617 %bookmark -r - remove all bookmarks
618 618
619 619 You can later on access a bookmarked folder with::
620 620
621 621 %cd -b <name>
622 622
623 623 or simply '%cd <name>' if there is no directory called <name> AND
624 624 there is such a bookmark defined.
625 625
626 626 Your bookmarks persist through IPython sessions, but they are
627 627 associated with each profile."""
628 628
629 629 opts,args = self.parse_options(parameter_s,'drl',mode='list')
630 630 if len(args) > 2:
631 631 raise UsageError("%bookmark: too many arguments")
632 632
633 633 bkms = self.shell.db.get('bookmarks',{})
634 634
635 635 if 'd' in opts:
636 636 try:
637 637 todel = args[0]
638 638 except IndexError:
639 639 raise UsageError(
640 640 "%bookmark -d: must provide a bookmark to delete")
641 641 else:
642 642 try:
643 643 del bkms[todel]
644 644 except KeyError:
645 645 raise UsageError(
646 646 "%%bookmark -d: Can't delete bookmark '%s'" % todel)
647 647
648 648 elif 'r' in opts:
649 649 bkms = {}
650 650 elif 'l' in opts:
651 651 bks = bkms.keys()
652 652 bks.sort()
653 653 if bks:
654 654 size = max(map(len, bks))
655 655 else:
656 656 size = 0
657 657 fmt = '%-'+str(size)+'s -> %s'
658 658 print 'Current bookmarks:'
659 659 for bk in bks:
660 660 print fmt % (bk, bkms[bk])
661 661 else:
662 662 if not args:
663 663 raise UsageError("%bookmark: You must specify the bookmark name")
664 664 elif len(args)==1:
665 665 bkms[args[0]] = os.getcwdu()
666 666 elif len(args)==2:
667 667 bkms[args[0]] = args[1]
668 668 self.shell.db['bookmarks'] = bkms
669 669
670 670 @line_magic
671 671 def pycat(self, parameter_s=''):
672 672 """Show a syntax-highlighted file through a pager.
673 673
674 674 This magic is similar to the cat utility, but it will assume the file
675 675 to be Python source and will show it with syntax highlighting.
676 676
677 677 This magic command can either take a local filename, an url,
678 678 an history range (see %history) or a macro as argument ::
679 679
680 680 %pycat myscript.py
681 681 %pycat 7-27
682 682 %pycat myMacro
683 683 %pycat http://www.example.com/myscript.py
684 684 """
685 685 if not parameter_s:
686 686 raise UsageError('Missing filename, URL, input history range, '
687 687 'or macro.')
688 688
689 689 try :
690 690 cont = self.shell.find_user_code(parameter_s, skip_encoding_cookie=False)
691 691 except (ValueError, IOError):
692 692 print "Error: no such file, variable, URL, history range or macro"
693 693 return
694 694
695 695 page.page(self.shell.pycolorize(source_to_unicode(cont)))
696 696
697 697 @magic_arguments.magic_arguments()
698 698 @magic_arguments.argument(
699 699 '-a', '--amend', action='store_true', default=False,
700 700 help='Open file for amending if it exists'
701 701 )
702 702 @magic_arguments.argument(
703 703 'filename', type=unicode,
704 704 help='file to write'
705 705 )
706 706 @cell_magic
707 707 def file(self, line, cell):
708 708 """Write the contents of the cell to a file.
709 709
710 710 For frontends that do not support stdin (Notebook), -f is implied.
711 711 """
712 712 args = magic_arguments.parse_argstring(self.file, line)
713 713 filename = unquote_filename(args.filename)
714 714
715 715 if os.path.exists(filename):
716 716 if args.amend:
717 717 print "Amending to %s" % filename
718 718 else:
719 719 print "Overwriting %s" % filename
720 720 else:
721 721 print "Writing %s" % filename
722 722
723 723 mode = 'a' if args.amend else 'w'
724 724 with io.open(filename, mode, encoding='utf-8') as f:
725 725 f.write(cell)
@@ -1,283 +1,280 b''
1 1 """Magic functions for running cells in various scripts."""
2 2 #-----------------------------------------------------------------------------
3 3 # Copyright (c) 2012 The IPython Development Team.
4 4 #
5 5 # Distributed under the terms of the Modified BSD License.
6 6 #
7 7 # The full license is in the file COPYING.txt, distributed with this software.
8 8 #-----------------------------------------------------------------------------
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Imports
12 12 #-----------------------------------------------------------------------------
13 13
14 14 # Stdlib
15 15 import errno
16 16 import os
17 import re
18 17 import sys
19 18 import signal
20 19 import time
21 20 from subprocess import Popen, PIPE
22 21 import atexit
23 22
24 23 # Our own packages
25 24 from IPython.config.configurable import Configurable
26 25 from IPython.core import magic_arguments
27 from IPython.core.error import UsageError
28 26 from IPython.core.magic import (
29 27 Magics, magics_class, line_magic, cell_magic
30 28 )
31 29 from IPython.lib.backgroundjobs import BackgroundJobManager
32 from IPython.testing.skipdoctest import skip_doctest
33 30 from IPython.utils import py3compat
34 31 from IPython.utils.process import arg_split
35 32 from IPython.utils.traitlets import List, Dict
36 33
37 34 #-----------------------------------------------------------------------------
38 35 # Magic implementation classes
39 36 #-----------------------------------------------------------------------------
40 37
41 38 def script_args(f):
42 39 """single decorator for adding script args"""
43 40 args = [
44 41 magic_arguments.argument(
45 42 '--out', type=str,
46 43 help="""The variable in which to store stdout from the script.
47 44 If the script is backgrounded, this will be the stdout *pipe*,
48 45 instead of the stderr text itself.
49 46 """
50 47 ),
51 48 magic_arguments.argument(
52 49 '--err', type=str,
53 50 help="""The variable in which to store stderr from the script.
54 51 If the script is backgrounded, this will be the stderr *pipe*,
55 52 instead of the stderr text itself.
56 53 """
57 54 ),
58 55 magic_arguments.argument(
59 56 '--bg', action="store_true",
60 57 help="""Whether to run the script in the background.
61 58 If given, the only way to see the output of the command is
62 59 with --out/err.
63 60 """
64 61 ),
65 62 magic_arguments.argument(
66 63 '--proc', type=str,
67 64 help="""The variable in which to store Popen instance.
68 65 This is used only when --bg option is given.
69 66 """
70 67 ),
71 68 ]
72 69 for arg in args:
73 70 f = arg(f)
74 71 return f
75 72
76 73 @magics_class
77 74 class ScriptMagics(Magics, Configurable):
78 75 """Magics for talking to scripts
79 76
80 77 This defines a base `%%script` cell magic for running a cell
81 78 with a program in a subprocess, and registers a few top-level
82 79 magics that call %%script with common interpreters.
83 80 """
84 81 script_magics = List(config=True,
85 82 help="""Extra script cell magics to define
86 83
87 84 This generates simple wrappers of `%%script foo` as `%%foo`.
88 85
89 86 If you want to add script magics that aren't on your path,
90 87 specify them in script_paths
91 88 """,
92 89 )
93 90 def _script_magics_default(self):
94 91 """default to a common list of programs"""
95 92
96 93 defaults = [
97 94 'sh',
98 95 'bash',
99 96 'perl',
100 97 'ruby',
101 98 'python',
102 99 'python3',
103 100 'pypy',
104 101 ]
105 102 if os.name == 'nt':
106 103 defaults.extend([
107 104 'cmd',
108 105 'powershell',
109 106 ])
110 107
111 108 return defaults
112 109
113 110 script_paths = Dict(config=True,
114 111 help="""Dict mapping short 'ruby' names to full paths, such as '/opt/secret/bin/ruby'
115 112
116 113 Only necessary for items in script_magics where the default path will not
117 114 find the right interpreter.
118 115 """
119 116 )
120 117
121 118 def __init__(self, shell=None):
122 119 Configurable.__init__(self, config=shell.config)
123 120 self._generate_script_magics()
124 121 Magics.__init__(self, shell=shell)
125 122 self.job_manager = BackgroundJobManager()
126 123 self.bg_processes = []
127 124 atexit.register(self.kill_bg_processes)
128 125
129 126 def __del__(self):
130 127 self.kill_bg_processes()
131 128
132 129 def _generate_script_magics(self):
133 130 cell_magics = self.magics['cell']
134 131 for name in self.script_magics:
135 132 cell_magics[name] = self._make_script_magic(name)
136 133
137 134 def _make_script_magic(self, name):
138 135 """make a named magic, that calls %%script with a particular program"""
139 136 # expand to explicit path if necessary:
140 137 script = self.script_paths.get(name, name)
141 138
142 139 @magic_arguments.magic_arguments()
143 140 @script_args
144 141 def named_script_magic(line, cell):
145 142 # if line, add it as cl-flags
146 143 if line:
147 144 line = "%s %s" % (script, line)
148 145 else:
149 146 line = script
150 147 return self.shebang(line, cell)
151 148
152 149 # write a basic docstring:
153 150 named_script_magic.__doc__ = \
154 151 """%%{name} script magic
155 152
156 153 Run cells with {script} in a subprocess.
157 154
158 155 This is a shortcut for `%%script {script}`
159 156 """.format(**locals())
160 157
161 158 return named_script_magic
162 159
163 160 @magic_arguments.magic_arguments()
164 161 @script_args
165 162 @cell_magic("script")
166 163 def shebang(self, line, cell):
167 164 """Run a cell via a shell command
168 165
169 166 The `%%script` line is like the #! line of script,
170 167 specifying a program (bash, perl, ruby, etc.) with which to run.
171 168
172 169 The rest of the cell is run by that program.
173 170
174 171 Examples
175 172 --------
176 173 ::
177 174
178 175 In [1]: %%script bash
179 176 ...: for i in 1 2 3; do
180 177 ...: echo $i
181 178 ...: done
182 179 1
183 180 2
184 181 3
185 182 """
186 183 argv = arg_split(line, posix = not sys.platform.startswith('win'))
187 184 args, cmd = self.shebang.parser.parse_known_args(argv)
188 185
189 186 try:
190 187 p = Popen(cmd, stdout=PIPE, stderr=PIPE, stdin=PIPE)
191 188 except OSError as e:
192 189 if e.errno == errno.ENOENT:
193 190 print "Couldn't find program: %r" % cmd[0]
194 191 return
195 192 else:
196 193 raise
197 194
198 195 cell = cell.encode('utf8', 'replace')
199 196 if args.bg:
200 197 self.bg_processes.append(p)
201 198 self._gc_bg_processes()
202 199 if args.out:
203 200 self.shell.user_ns[args.out] = p.stdout
204 201 if args.err:
205 202 self.shell.user_ns[args.err] = p.stderr
206 203 self.job_manager.new(self._run_script, p, cell, daemon=True)
207 204 if args.proc:
208 205 self.shell.user_ns[args.proc] = p
209 206 return
210 207
211 208 try:
212 209 out, err = p.communicate(cell)
213 210 except KeyboardInterrupt:
214 211 try:
215 212 p.send_signal(signal.SIGINT)
216 213 time.sleep(0.1)
217 214 if p.poll() is not None:
218 215 print "Process is interrupted."
219 216 return
220 217 p.terminate()
221 218 time.sleep(0.1)
222 219 if p.poll() is not None:
223 220 print "Process is terminated."
224 221 return
225 222 p.kill()
226 223 print "Process is killed."
227 224 except OSError:
228 225 pass
229 226 except Exception as e:
230 227 print "Error while terminating subprocess (pid=%i): %s" \
231 228 % (p.pid, e)
232 229 return
233 230 out = py3compat.bytes_to_str(out)
234 231 err = py3compat.bytes_to_str(err)
235 232 if args.out:
236 233 self.shell.user_ns[args.out] = out
237 234 else:
238 235 sys.stdout.write(out)
239 236 sys.stdout.flush()
240 237 if args.err:
241 238 self.shell.user_ns[args.err] = err
242 239 else:
243 240 sys.stderr.write(err)
244 241 sys.stderr.flush()
245 242
246 243 def _run_script(self, p, cell):
247 244 """callback for running the script in the background"""
248 245 p.stdin.write(cell)
249 246 p.stdin.close()
250 247 p.wait()
251 248
252 249 @line_magic("killbgscripts")
253 250 def killbgscripts(self, _nouse_=''):
254 251 """Kill all BG processes started by %%script and its family."""
255 252 self.kill_bg_processes()
256 253 print "All background processes were killed."
257 254
258 255 def kill_bg_processes(self):
259 256 """Kill all BG processes which are still running."""
260 257 for p in self.bg_processes:
261 258 if p.poll() is None:
262 259 try:
263 260 p.send_signal(signal.SIGINT)
264 261 except:
265 262 pass
266 263 time.sleep(0.1)
267 264 for p in self.bg_processes:
268 265 if p.poll() is None:
269 266 try:
270 267 p.terminate()
271 268 except:
272 269 pass
273 270 time.sleep(0.1)
274 271 for p in self.bg_processes:
275 272 if p.poll() is None:
276 273 try:
277 274 p.kill()
278 275 except:
279 276 pass
280 277 self._gc_bg_processes()
281 278
282 279 def _gc_bg_processes(self):
283 280 self.bg_processes = [p for p in self.bg_processes if p.poll() is None]
@@ -1,349 +1,348 b''
1 1 # encoding: utf-8
2 2 """
3 3 Paging capabilities for IPython.core
4 4
5 5 Authors:
6 6
7 7 * Brian Granger
8 8 * Fernando Perez
9 9
10 10 Notes
11 11 -----
12 12
13 13 For now this uses ipapi, so it can't be in IPython.utils. If we can get
14 14 rid of that dependency, we could move it there.
15 15 -----
16 16 """
17 17
18 18 #-----------------------------------------------------------------------------
19 19 # Copyright (C) 2008-2011 The IPython Development Team
20 20 #
21 21 # Distributed under the terms of the BSD License. The full license is in
22 22 # the file COPYING, distributed as part of this software.
23 23 #-----------------------------------------------------------------------------
24 24
25 25 #-----------------------------------------------------------------------------
26 26 # Imports
27 27 #-----------------------------------------------------------------------------
28 28 from __future__ import print_function
29 29
30 30 import os
31 31 import re
32 import subprocess
33 32 import sys
34 33 import tempfile
35 34
36 35 from io import UnsupportedOperation
37 36
38 37 from IPython.core import ipapi
39 38 from IPython.core.error import TryNext
40 39 from IPython.utils.data import chop
41 40 from IPython.utils import io
42 41 from IPython.utils.process import system
43 42 from IPython.utils.terminal import get_terminal_size
44 43 from IPython.utils import py3compat
45 44
46 45
47 46 #-----------------------------------------------------------------------------
48 47 # Classes and functions
49 48 #-----------------------------------------------------------------------------
50 49
51 50 esc_re = re.compile(r"(\x1b[^m]+m)")
52 51
53 52 def page_dumb(strng, start=0, screen_lines=25):
54 53 """Very dumb 'pager' in Python, for when nothing else works.
55 54
56 55 Only moves forward, same interface as page(), except for pager_cmd and
57 56 mode."""
58 57
59 58 out_ln = strng.splitlines()[start:]
60 59 screens = chop(out_ln,screen_lines-1)
61 60 if len(screens) == 1:
62 61 print(os.linesep.join(screens[0]), file=io.stdout)
63 62 else:
64 63 last_escape = ""
65 64 for scr in screens[0:-1]:
66 65 hunk = os.linesep.join(scr)
67 66 print(last_escape + hunk, file=io.stdout)
68 67 if not page_more():
69 68 return
70 69 esc_list = esc_re.findall(hunk)
71 70 if len(esc_list) > 0:
72 71 last_escape = esc_list[-1]
73 72 print(last_escape + os.linesep.join(screens[-1]), file=io.stdout)
74 73
75 74 def _detect_screen_size(screen_lines_def):
76 75 """Attempt to work out the number of lines on the screen.
77 76
78 77 This is called by page(). It can raise an error (e.g. when run in the
79 78 test suite), so it's separated out so it can easily be called in a try block.
80 79 """
81 80 TERM = os.environ.get('TERM',None)
82 81 if not((TERM=='xterm' or TERM=='xterm-color') and sys.platform != 'sunos5'):
83 82 # curses causes problems on many terminals other than xterm, and
84 83 # some termios calls lock up on Sun OS5.
85 84 return screen_lines_def
86 85
87 86 try:
88 87 import termios
89 88 import curses
90 89 except ImportError:
91 90 return screen_lines_def
92 91
93 92 # There is a bug in curses, where *sometimes* it fails to properly
94 93 # initialize, and then after the endwin() call is made, the
95 94 # terminal is left in an unusable state. Rather than trying to
96 95 # check everytime for this (by requesting and comparing termios
97 96 # flags each time), we just save the initial terminal state and
98 97 # unconditionally reset it every time. It's cheaper than making
99 98 # the checks.
100 99 term_flags = termios.tcgetattr(sys.stdout)
101 100
102 101 # Curses modifies the stdout buffer size by default, which messes
103 102 # up Python's normal stdout buffering. This would manifest itself
104 103 # to IPython users as delayed printing on stdout after having used
105 104 # the pager.
106 105 #
107 106 # We can prevent this by manually setting the NCURSES_NO_SETBUF
108 107 # environment variable. For more details, see:
109 108 # http://bugs.python.org/issue10144
110 109 NCURSES_NO_SETBUF = os.environ.get('NCURSES_NO_SETBUF', None)
111 110 os.environ['NCURSES_NO_SETBUF'] = ''
112 111
113 112 # Proceed with curses initialization
114 113 try:
115 114 scr = curses.initscr()
116 115 except AttributeError:
117 116 # Curses on Solaris may not be complete, so we can't use it there
118 117 return screen_lines_def
119 118
120 119 screen_lines_real,screen_cols = scr.getmaxyx()
121 120 curses.endwin()
122 121
123 122 # Restore environment
124 123 if NCURSES_NO_SETBUF is None:
125 124 del os.environ['NCURSES_NO_SETBUF']
126 125 else:
127 126 os.environ['NCURSES_NO_SETBUF'] = NCURSES_NO_SETBUF
128 127
129 128 # Restore terminal state in case endwin() didn't.
130 129 termios.tcsetattr(sys.stdout,termios.TCSANOW,term_flags)
131 130 # Now we have what we needed: the screen size in rows/columns
132 131 return screen_lines_real
133 132 #print '***Screen size:',screen_lines_real,'lines x',\
134 133 #screen_cols,'columns.' # dbg
135 134
136 135 def page(strng, start=0, screen_lines=0, pager_cmd=None):
137 136 """Print a string, piping through a pager after a certain length.
138 137
139 138 The screen_lines parameter specifies the number of *usable* lines of your
140 139 terminal screen (total lines minus lines you need to reserve to show other
141 140 information).
142 141
143 142 If you set screen_lines to a number <=0, page() will try to auto-determine
144 143 your screen size and will only use up to (screen_size+screen_lines) for
145 144 printing, paging after that. That is, if you want auto-detection but need
146 145 to reserve the bottom 3 lines of the screen, use screen_lines = -3, and for
147 146 auto-detection without any lines reserved simply use screen_lines = 0.
148 147
149 148 If a string won't fit in the allowed lines, it is sent through the
150 149 specified pager command. If none given, look for PAGER in the environment,
151 150 and ultimately default to less.
152 151
153 152 If no system pager works, the string is sent through a 'dumb pager'
154 153 written in python, very simplistic.
155 154 """
156 155
157 156 # Some routines may auto-compute start offsets incorrectly and pass a
158 157 # negative value. Offset to 0 for robustness.
159 158 start = max(0, start)
160 159
161 160 # first, try the hook
162 161 ip = ipapi.get()
163 162 if ip:
164 163 try:
165 164 ip.hooks.show_in_pager(strng)
166 165 return
167 166 except TryNext:
168 167 pass
169 168
170 169 # Ugly kludge, but calling curses.initscr() flat out crashes in emacs
171 170 TERM = os.environ.get('TERM','dumb')
172 171 if TERM in ['dumb','emacs'] and os.name != 'nt':
173 172 print(strng)
174 173 return
175 174 # chop off the topmost part of the string we don't want to see
176 175 str_lines = strng.splitlines()[start:]
177 176 str_toprint = os.linesep.join(str_lines)
178 177 num_newlines = len(str_lines)
179 178 len_str = len(str_toprint)
180 179
181 180 # Dumb heuristics to guesstimate number of on-screen lines the string
182 181 # takes. Very basic, but good enough for docstrings in reasonable
183 182 # terminals. If someone later feels like refining it, it's not hard.
184 183 numlines = max(num_newlines,int(len_str/80)+1)
185 184
186 185 screen_lines_def = get_terminal_size()[1]
187 186
188 187 # auto-determine screen size
189 188 if screen_lines <= 0:
190 189 try:
191 190 screen_lines += _detect_screen_size(screen_lines_def)
192 191 except (TypeError, UnsupportedOperation):
193 192 print(str_toprint, file=io.stdout)
194 193 return
195 194
196 195 #print 'numlines',numlines,'screenlines',screen_lines # dbg
197 196 if numlines <= screen_lines :
198 197 #print '*** normal print' # dbg
199 198 print(str_toprint, file=io.stdout)
200 199 else:
201 200 # Try to open pager and default to internal one if that fails.
202 201 # All failure modes are tagged as 'retval=1', to match the return
203 202 # value of a failed system command. If any intermediate attempt
204 203 # sets retval to 1, at the end we resort to our own page_dumb() pager.
205 204 pager_cmd = get_pager_cmd(pager_cmd)
206 205 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
207 206 if os.name == 'nt':
208 207 if pager_cmd.startswith('type'):
209 208 # The default WinXP 'type' command is failing on complex strings.
210 209 retval = 1
211 210 else:
212 211 tmpname = tempfile.mktemp('.txt')
213 212 tmpfile = open(tmpname,'wt')
214 213 tmpfile.write(strng)
215 214 tmpfile.close()
216 215 cmd = "%s < %s" % (pager_cmd,tmpname)
217 216 if os.system(cmd):
218 217 retval = 1
219 218 else:
220 219 retval = None
221 220 os.remove(tmpname)
222 221 else:
223 222 try:
224 223 retval = None
225 224 # if I use popen4, things hang. No idea why.
226 225 #pager,shell_out = os.popen4(pager_cmd)
227 226 pager = os.popen(pager_cmd, 'w')
228 227 try:
229 228 pager_encoding = pager.encoding or sys.stdout.encoding
230 229 pager.write(py3compat.cast_bytes_py2(
231 230 strng, encoding=pager_encoding))
232 231 finally:
233 232 retval = pager.close()
234 233 except IOError as msg: # broken pipe when user quits
235 234 if msg.args == (32, 'Broken pipe'):
236 235 retval = None
237 236 else:
238 237 retval = 1
239 238 except OSError:
240 239 # Other strange problems, sometimes seen in Win2k/cygwin
241 240 retval = 1
242 241 if retval is not None:
243 242 page_dumb(strng,screen_lines=screen_lines)
244 243
245 244
246 245 def page_file(fname, start=0, pager_cmd=None):
247 246 """Page a file, using an optional pager command and starting line.
248 247 """
249 248
250 249 pager_cmd = get_pager_cmd(pager_cmd)
251 250 pager_cmd += ' ' + get_pager_start(pager_cmd,start)
252 251
253 252 try:
254 253 if os.environ['TERM'] in ['emacs','dumb']:
255 254 raise EnvironmentError
256 255 system(pager_cmd + ' ' + fname)
257 256 except:
258 257 try:
259 258 if start > 0:
260 259 start -= 1
261 260 page(open(fname).read(),start)
262 261 except:
263 262 print('Unable to show file',repr(fname))
264 263
265 264
266 265 def get_pager_cmd(pager_cmd=None):
267 266 """Return a pager command.
268 267
269 268 Makes some attempts at finding an OS-correct one.
270 269 """
271 270 if os.name == 'posix':
272 271 default_pager_cmd = 'less -r' # -r for color control sequences
273 272 elif os.name in ['nt','dos']:
274 273 default_pager_cmd = 'type'
275 274
276 275 if pager_cmd is None:
277 276 try:
278 277 pager_cmd = os.environ['PAGER']
279 278 except:
280 279 pager_cmd = default_pager_cmd
281 280 return pager_cmd
282 281
283 282
284 283 def get_pager_start(pager, start):
285 284 """Return the string for paging files with an offset.
286 285
287 286 This is the '+N' argument which less and more (under Unix) accept.
288 287 """
289 288
290 289 if pager in ['less','more']:
291 290 if start:
292 291 start_string = '+' + str(start)
293 292 else:
294 293 start_string = ''
295 294 else:
296 295 start_string = ''
297 296 return start_string
298 297
299 298
300 299 # (X)emacs on win32 doesn't like to be bypassed with msvcrt.getch()
301 300 if os.name == 'nt' and os.environ.get('TERM','dumb') != 'emacs':
302 301 import msvcrt
303 302 def page_more():
304 303 """ Smart pausing between pages
305 304
306 305 @return: True if need print more lines, False if quit
307 306 """
308 307 io.stdout.write('---Return to continue, q to quit--- ')
309 308 ans = msvcrt.getch()
310 309 if ans in ("q", "Q"):
311 310 result = False
312 311 else:
313 312 result = True
314 313 io.stdout.write("\b"*37 + " "*37 + "\b"*37)
315 314 return result
316 315 else:
317 316 def page_more():
318 317 ans = raw_input('---Return to continue, q to quit--- ')
319 318 if ans.lower().startswith('q'):
320 319 return False
321 320 else:
322 321 return True
323 322
324 323
325 324 def snip_print(str,width = 75,print_full = 0,header = ''):
326 325 """Print a string snipping the midsection to fit in width.
327 326
328 327 print_full: mode control:
329 328 - 0: only snip long strings
330 329 - 1: send to page() directly.
331 330 - 2: snip long strings and ask for full length viewing with page()
332 331 Return 1 if snipping was necessary, 0 otherwise."""
333 332
334 333 if print_full == 1:
335 334 page(header+str)
336 335 return 0
337 336
338 337 print(header, end=' ')
339 338 if len(str) < width:
340 339 print(str)
341 340 snip = 0
342 341 else:
343 342 whalf = int((width -5)/2)
344 343 print(str[:whalf] + ' <...> ' + str[-whalf:])
345 344 snip = 1
346 345 if snip and print_full == 2:
347 346 if raw_input(header+' Snipped. View (y/n)? [N]').lower() == 'y':
348 347 page(str)
349 348 return snip
@@ -1,754 +1,749 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 Authors:
9 9
10 10 * Brian Granger
11 11 * Fernando Perez
12 12 * Dan Milstein
13 13 * Ville Vainio
14 14 """
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Copyright (C) 2008-2011 The IPython Development Team
18 18 #
19 19 # Distributed under the terms of the BSD License. The full license is in
20 20 # the file COPYING, distributed as part of this software.
21 21 #-----------------------------------------------------------------------------
22 22
23 23 #-----------------------------------------------------------------------------
24 24 # Imports
25 25 #-----------------------------------------------------------------------------
26 26
27 import __builtin__
28 import codeop
29 27 import re
30 28
31 from IPython.core.alias import AliasManager
32 29 from IPython.core.autocall import IPyAutocall
33 30 from IPython.config.configurable import Configurable
34 31 from IPython.core.inputsplitter import (
35 32 ESC_SHELL,
36 33 ESC_SH_CAP,
37 34 ESC_HELP,
38 35 ESC_MAGIC,
39 36 ESC_MAGIC2,
40 37 ESC_QUOTE,
41 38 ESC_QUOTE2,
42 39 ESC_PAREN,
43 40 )
44 41 from IPython.core.macro import Macro
45 from IPython.core.splitinput import split_user_input, LineInfo
46 from IPython.core import page
42 from IPython.core.splitinput import LineInfo
47 43
48 44 from IPython.utils.traitlets import (
49 List, Integer, Any, Unicode, CBool, Bool, Instance, CRegExp
45 List, Integer, Unicode, CBool, Bool, Instance, CRegExp
50 46 )
51 from IPython.utils.autoattr import auto_attr
52 47
53 48 #-----------------------------------------------------------------------------
54 49 # Global utilities, errors and constants
55 50 #-----------------------------------------------------------------------------
56 51
57 52
58 53 class PrefilterError(Exception):
59 54 pass
60 55
61 56
62 57 # RegExp to identify potential function names
63 58 re_fun_name = re.compile(r'[a-zA-Z_]([a-zA-Z0-9_.]*) *$')
64 59
65 60 # RegExp to exclude strings with this start from autocalling. In
66 61 # particular, all binary operators should be excluded, so that if foo is
67 62 # callable, foo OP bar doesn't become foo(OP bar), which is invalid. The
68 63 # characters '!=()' don't need to be checked for, as the checkPythonChars
69 64 # routine explicitely does so, to catch direct calls and rebindings of
70 65 # existing names.
71 66
72 67 # Warning: the '-' HAS TO BE AT THE END of the first group, otherwise
73 68 # it affects the rest of the group in square brackets.
74 69 re_exclude_auto = re.compile(r'^[,&^\|\*/\+-]'
75 70 r'|^is |^not |^in |^and |^or ')
76 71
77 72 # try to catch also methods for stuff in lists/tuples/dicts: off
78 73 # (experimental). For this to work, the line_split regexp would need
79 74 # to be modified so it wouldn't break things at '['. That line is
80 75 # nasty enough that I shouldn't change it until I can test it _well_.
81 76 #self.re_fun_name = re.compile (r'[a-zA-Z_]([a-zA-Z0-9_.\[\]]*) ?$')
82 77
83 78
84 79 # Handler Check Utilities
85 80 def is_shadowed(identifier, ip):
86 81 """Is the given identifier defined in one of the namespaces which shadow
87 82 the alias and magic namespaces? Note that an identifier is different
88 83 than ifun, because it can not contain a '.' character."""
89 84 # This is much safer than calling ofind, which can change state
90 85 return (identifier in ip.user_ns \
91 86 or identifier in ip.user_global_ns \
92 87 or identifier in ip.ns_table['builtin'])
93 88
94 89
95 90 #-----------------------------------------------------------------------------
96 91 # Main Prefilter manager
97 92 #-----------------------------------------------------------------------------
98 93
99 94
100 95 class PrefilterManager(Configurable):
101 96 """Main prefilter component.
102 97
103 98 The IPython prefilter is run on all user input before it is run. The
104 99 prefilter consumes lines of input and produces transformed lines of
105 100 input.
106 101
107 102 The iplementation consists of two phases:
108 103
109 104 1. Transformers
110 105 2. Checkers and handlers
111 106
112 107 Over time, we plan on deprecating the checkers and handlers and doing
113 108 everything in the transformers.
114 109
115 110 The transformers are instances of :class:`PrefilterTransformer` and have
116 111 a single method :meth:`transform` that takes a line and returns a
117 112 transformed line. The transformation can be accomplished using any
118 113 tool, but our current ones use regular expressions for speed.
119 114
120 115 After all the transformers have been run, the line is fed to the checkers,
121 116 which are instances of :class:`PrefilterChecker`. The line is passed to
122 117 the :meth:`check` method, which either returns `None` or a
123 118 :class:`PrefilterHandler` instance. If `None` is returned, the other
124 119 checkers are tried. If an :class:`PrefilterHandler` instance is returned,
125 120 the line is passed to the :meth:`handle` method of the returned
126 121 handler and no further checkers are tried.
127 122
128 123 Both transformers and checkers have a `priority` attribute, that determines
129 124 the order in which they are called. Smaller priorities are tried first.
130 125
131 126 Both transformers and checkers also have `enabled` attribute, which is
132 127 a boolean that determines if the instance is used.
133 128
134 129 Users or developers can change the priority or enabled attribute of
135 130 transformers or checkers, but they must call the :meth:`sort_checkers`
136 131 or :meth:`sort_transformers` method after changing the priority.
137 132 """
138 133
139 134 multi_line_specials = CBool(True, config=True)
140 135 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
141 136
142 137 def __init__(self, shell=None, config=None):
143 138 super(PrefilterManager, self).__init__(shell=shell, config=config)
144 139 self.shell = shell
145 140 self.init_transformers()
146 141 self.init_handlers()
147 142 self.init_checkers()
148 143
149 144 #-------------------------------------------------------------------------
150 145 # API for managing transformers
151 146 #-------------------------------------------------------------------------
152 147
153 148 def init_transformers(self):
154 149 """Create the default transformers."""
155 150 self._transformers = []
156 151 for transformer_cls in _default_transformers:
157 152 transformer_cls(
158 153 shell=self.shell, prefilter_manager=self, config=self.config
159 154 )
160 155
161 156 def sort_transformers(self):
162 157 """Sort the transformers by priority.
163 158
164 159 This must be called after the priority of a transformer is changed.
165 160 The :meth:`register_transformer` method calls this automatically.
166 161 """
167 162 self._transformers.sort(key=lambda x: x.priority)
168 163
169 164 @property
170 165 def transformers(self):
171 166 """Return a list of checkers, sorted by priority."""
172 167 return self._transformers
173 168
174 169 def register_transformer(self, transformer):
175 170 """Register a transformer instance."""
176 171 if transformer not in self._transformers:
177 172 self._transformers.append(transformer)
178 173 self.sort_transformers()
179 174
180 175 def unregister_transformer(self, transformer):
181 176 """Unregister a transformer instance."""
182 177 if transformer in self._transformers:
183 178 self._transformers.remove(transformer)
184 179
185 180 #-------------------------------------------------------------------------
186 181 # API for managing checkers
187 182 #-------------------------------------------------------------------------
188 183
189 184 def init_checkers(self):
190 185 """Create the default checkers."""
191 186 self._checkers = []
192 187 for checker in _default_checkers:
193 188 checker(
194 189 shell=self.shell, prefilter_manager=self, config=self.config
195 190 )
196 191
197 192 def sort_checkers(self):
198 193 """Sort the checkers by priority.
199 194
200 195 This must be called after the priority of a checker is changed.
201 196 The :meth:`register_checker` method calls this automatically.
202 197 """
203 198 self._checkers.sort(key=lambda x: x.priority)
204 199
205 200 @property
206 201 def checkers(self):
207 202 """Return a list of checkers, sorted by priority."""
208 203 return self._checkers
209 204
210 205 def register_checker(self, checker):
211 206 """Register a checker instance."""
212 207 if checker not in self._checkers:
213 208 self._checkers.append(checker)
214 209 self.sort_checkers()
215 210
216 211 def unregister_checker(self, checker):
217 212 """Unregister a checker instance."""
218 213 if checker in self._checkers:
219 214 self._checkers.remove(checker)
220 215
221 216 #-------------------------------------------------------------------------
222 217 # API for managing checkers
223 218 #-------------------------------------------------------------------------
224 219
225 220 def init_handlers(self):
226 221 """Create the default handlers."""
227 222 self._handlers = {}
228 223 self._esc_handlers = {}
229 224 for handler in _default_handlers:
230 225 handler(
231 226 shell=self.shell, prefilter_manager=self, config=self.config
232 227 )
233 228
234 229 @property
235 230 def handlers(self):
236 231 """Return a dict of all the handlers."""
237 232 return self._handlers
238 233
239 234 def register_handler(self, name, handler, esc_strings):
240 235 """Register a handler instance by name with esc_strings."""
241 236 self._handlers[name] = handler
242 237 for esc_str in esc_strings:
243 238 self._esc_handlers[esc_str] = handler
244 239
245 240 def unregister_handler(self, name, handler, esc_strings):
246 241 """Unregister a handler instance by name with esc_strings."""
247 242 try:
248 243 del self._handlers[name]
249 244 except KeyError:
250 245 pass
251 246 for esc_str in esc_strings:
252 247 h = self._esc_handlers.get(esc_str)
253 248 if h is handler:
254 249 del self._esc_handlers[esc_str]
255 250
256 251 def get_handler_by_name(self, name):
257 252 """Get a handler by its name."""
258 253 return self._handlers.get(name)
259 254
260 255 def get_handler_by_esc(self, esc_str):
261 256 """Get a handler by its escape string."""
262 257 return self._esc_handlers.get(esc_str)
263 258
264 259 #-------------------------------------------------------------------------
265 260 # Main prefiltering API
266 261 #-------------------------------------------------------------------------
267 262
268 263 def prefilter_line_info(self, line_info):
269 264 """Prefilter a line that has been converted to a LineInfo object.
270 265
271 266 This implements the checker/handler part of the prefilter pipe.
272 267 """
273 268 # print "prefilter_line_info: ", line_info
274 269 handler = self.find_handler(line_info)
275 270 return handler.handle(line_info)
276 271
277 272 def find_handler(self, line_info):
278 273 """Find a handler for the line_info by trying checkers."""
279 274 for checker in self.checkers:
280 275 if checker.enabled:
281 276 handler = checker.check(line_info)
282 277 if handler:
283 278 return handler
284 279 return self.get_handler_by_name('normal')
285 280
286 281 def transform_line(self, line, continue_prompt):
287 282 """Calls the enabled transformers in order of increasing priority."""
288 283 for transformer in self.transformers:
289 284 if transformer.enabled:
290 285 line = transformer.transform(line, continue_prompt)
291 286 return line
292 287
293 288 def prefilter_line(self, line, continue_prompt=False):
294 289 """Prefilter a single input line as text.
295 290
296 291 This method prefilters a single line of text by calling the
297 292 transformers and then the checkers/handlers.
298 293 """
299 294
300 295 # print "prefilter_line: ", line, continue_prompt
301 296 # All handlers *must* return a value, even if it's blank ('').
302 297
303 298 # save the line away in case we crash, so the post-mortem handler can
304 299 # record it
305 300 self.shell._last_input_line = line
306 301
307 302 if not line:
308 303 # Return immediately on purely empty lines, so that if the user
309 304 # previously typed some whitespace that started a continuation
310 305 # prompt, he can break out of that loop with just an empty line.
311 306 # This is how the default python prompt works.
312 307 return ''
313 308
314 309 # At this point, we invoke our transformers.
315 310 if not continue_prompt or (continue_prompt and self.multi_line_specials):
316 311 line = self.transform_line(line, continue_prompt)
317 312
318 313 # Now we compute line_info for the checkers and handlers
319 314 line_info = LineInfo(line, continue_prompt)
320 315
321 316 # the input history needs to track even empty lines
322 317 stripped = line.strip()
323 318
324 319 normal_handler = self.get_handler_by_name('normal')
325 320 if not stripped:
326 321 return normal_handler.handle(line_info)
327 322
328 323 # special handlers are only allowed for single line statements
329 324 if continue_prompt and not self.multi_line_specials:
330 325 return normal_handler.handle(line_info)
331 326
332 327 prefiltered = self.prefilter_line_info(line_info)
333 328 # print "prefiltered line: %r" % prefiltered
334 329 return prefiltered
335 330
336 331 def prefilter_lines(self, lines, continue_prompt=False):
337 332 """Prefilter multiple input lines of text.
338 333
339 334 This is the main entry point for prefiltering multiple lines of
340 335 input. This simply calls :meth:`prefilter_line` for each line of
341 336 input.
342 337
343 338 This covers cases where there are multiple lines in the user entry,
344 339 which is the case when the user goes back to a multiline history
345 340 entry and presses enter.
346 341 """
347 342 llines = lines.rstrip('\n').split('\n')
348 343 # We can get multiple lines in one shot, where multiline input 'blends'
349 344 # into one line, in cases like recalling from the readline history
350 345 # buffer. We need to make sure that in such cases, we correctly
351 346 # communicate downstream which line is first and which are continuation
352 347 # ones.
353 348 if len(llines) > 1:
354 349 out = '\n'.join([self.prefilter_line(line, lnum>0)
355 350 for lnum, line in enumerate(llines) ])
356 351 else:
357 352 out = self.prefilter_line(llines[0], continue_prompt)
358 353
359 354 return out
360 355
361 356 #-----------------------------------------------------------------------------
362 357 # Prefilter transformers
363 358 #-----------------------------------------------------------------------------
364 359
365 360
366 361 class PrefilterTransformer(Configurable):
367 362 """Transform a line of user input."""
368 363
369 364 priority = Integer(100, config=True)
370 365 # Transformers don't currently use shell or prefilter_manager, but as we
371 366 # move away from checkers and handlers, they will need them.
372 367 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
373 368 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
374 369 enabled = Bool(True, config=True)
375 370
376 371 def __init__(self, shell=None, prefilter_manager=None, config=None):
377 372 super(PrefilterTransformer, self).__init__(
378 373 shell=shell, prefilter_manager=prefilter_manager, config=config
379 374 )
380 375 self.prefilter_manager.register_transformer(self)
381 376
382 377 def transform(self, line, continue_prompt):
383 378 """Transform a line, returning the new one."""
384 379 return None
385 380
386 381 def __repr__(self):
387 382 return "<%s(priority=%r, enabled=%r)>" % (
388 383 self.__class__.__name__, self.priority, self.enabled)
389 384
390 385
391 386 #-----------------------------------------------------------------------------
392 387 # Prefilter checkers
393 388 #-----------------------------------------------------------------------------
394 389
395 390
396 391 class PrefilterChecker(Configurable):
397 392 """Inspect an input line and return a handler for that line."""
398 393
399 394 priority = Integer(100, config=True)
400 395 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
401 396 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
402 397 enabled = Bool(True, config=True)
403 398
404 399 def __init__(self, shell=None, prefilter_manager=None, config=None):
405 400 super(PrefilterChecker, self).__init__(
406 401 shell=shell, prefilter_manager=prefilter_manager, config=config
407 402 )
408 403 self.prefilter_manager.register_checker(self)
409 404
410 405 def check(self, line_info):
411 406 """Inspect line_info and return a handler instance or None."""
412 407 return None
413 408
414 409 def __repr__(self):
415 410 return "<%s(priority=%r, enabled=%r)>" % (
416 411 self.__class__.__name__, self.priority, self.enabled)
417 412
418 413
419 414 class EmacsChecker(PrefilterChecker):
420 415
421 416 priority = Integer(100, config=True)
422 417 enabled = Bool(False, config=True)
423 418
424 419 def check(self, line_info):
425 420 "Emacs ipython-mode tags certain input lines."
426 421 if line_info.line.endswith('# PYTHON-MODE'):
427 422 return self.prefilter_manager.get_handler_by_name('emacs')
428 423 else:
429 424 return None
430 425
431 426
432 427 class MacroChecker(PrefilterChecker):
433 428
434 429 priority = Integer(250, config=True)
435 430
436 431 def check(self, line_info):
437 432 obj = self.shell.user_ns.get(line_info.ifun)
438 433 if isinstance(obj, Macro):
439 434 return self.prefilter_manager.get_handler_by_name('macro')
440 435 else:
441 436 return None
442 437
443 438
444 439 class IPyAutocallChecker(PrefilterChecker):
445 440
446 441 priority = Integer(300, config=True)
447 442
448 443 def check(self, line_info):
449 444 "Instances of IPyAutocall in user_ns get autocalled immediately"
450 445 obj = self.shell.user_ns.get(line_info.ifun, None)
451 446 if isinstance(obj, IPyAutocall):
452 447 obj.set_ip(self.shell)
453 448 return self.prefilter_manager.get_handler_by_name('auto')
454 449 else:
455 450 return None
456 451
457 452
458 453 class AssignmentChecker(PrefilterChecker):
459 454
460 455 priority = Integer(600, config=True)
461 456
462 457 def check(self, line_info):
463 458 """Check to see if user is assigning to a var for the first time, in
464 459 which case we want to avoid any sort of automagic / autocall games.
465 460
466 461 This allows users to assign to either alias or magic names true python
467 462 variables (the magic/alias systems always take second seat to true
468 463 python code). E.g. ls='hi', or ls,that=1,2"""
469 464 if line_info.the_rest:
470 465 if line_info.the_rest[0] in '=,':
471 466 return self.prefilter_manager.get_handler_by_name('normal')
472 467 else:
473 468 return None
474 469
475 470
476 471 class AutoMagicChecker(PrefilterChecker):
477 472
478 473 priority = Integer(700, config=True)
479 474
480 475 def check(self, line_info):
481 476 """If the ifun is magic, and automagic is on, run it. Note: normal,
482 477 non-auto magic would already have been triggered via '%' in
483 478 check_esc_chars. This just checks for automagic. Also, before
484 479 triggering the magic handler, make sure that there is nothing in the
485 480 user namespace which could shadow it."""
486 481 if not self.shell.automagic or not self.shell.find_magic(line_info.ifun):
487 482 return None
488 483
489 484 # We have a likely magic method. Make sure we should actually call it.
490 485 if line_info.continue_prompt and not self.prefilter_manager.multi_line_specials:
491 486 return None
492 487
493 488 head = line_info.ifun.split('.',1)[0]
494 489 if is_shadowed(head, self.shell):
495 490 return None
496 491
497 492 return self.prefilter_manager.get_handler_by_name('magic')
498 493
499 494
500 495 class AliasChecker(PrefilterChecker):
501 496
502 497 priority = Integer(800, config=True)
503 498
504 499 def check(self, line_info):
505 500 "Check if the initital identifier on the line is an alias."
506 501 # Note: aliases can not contain '.'
507 502 head = line_info.ifun.split('.',1)[0]
508 503 if line_info.ifun not in self.shell.alias_manager \
509 504 or head not in self.shell.alias_manager \
510 505 or is_shadowed(head, self.shell):
511 506 return None
512 507
513 508 return self.prefilter_manager.get_handler_by_name('alias')
514 509
515 510
516 511 class PythonOpsChecker(PrefilterChecker):
517 512
518 513 priority = Integer(900, config=True)
519 514
520 515 def check(self, line_info):
521 516 """If the 'rest' of the line begins with a function call or pretty much
522 517 any python operator, we should simply execute the line (regardless of
523 518 whether or not there's a possible autocall expansion). This avoids
524 519 spurious (and very confusing) geattr() accesses."""
525 520 if line_info.the_rest and line_info.the_rest[0] in '!=()<>,+*/%^&|':
526 521 return self.prefilter_manager.get_handler_by_name('normal')
527 522 else:
528 523 return None
529 524
530 525
531 526 class AutocallChecker(PrefilterChecker):
532 527
533 528 priority = Integer(1000, config=True)
534 529
535 530 function_name_regexp = CRegExp(re_fun_name, config=True,
536 531 help="RegExp to identify potential function names.")
537 532 exclude_regexp = CRegExp(re_exclude_auto, config=True,
538 533 help="RegExp to exclude strings with this start from autocalling.")
539 534
540 535 def check(self, line_info):
541 536 "Check if the initial word/function is callable and autocall is on."
542 537 if not self.shell.autocall:
543 538 return None
544 539
545 540 oinfo = line_info.ofind(self.shell) # This can mutate state via getattr
546 541 if not oinfo['found']:
547 542 return None
548 543
549 544 if callable(oinfo['obj']) \
550 545 and (not self.exclude_regexp.match(line_info.the_rest)) \
551 546 and self.function_name_regexp.match(line_info.ifun):
552 547 return self.prefilter_manager.get_handler_by_name('auto')
553 548 else:
554 549 return None
555 550
556 551
557 552 #-----------------------------------------------------------------------------
558 553 # Prefilter handlers
559 554 #-----------------------------------------------------------------------------
560 555
561 556
562 557 class PrefilterHandler(Configurable):
563 558
564 559 handler_name = Unicode('normal')
565 560 esc_strings = List([])
566 561 shell = Instance('IPython.core.interactiveshell.InteractiveShellABC')
567 562 prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager')
568 563
569 564 def __init__(self, shell=None, prefilter_manager=None, config=None):
570 565 super(PrefilterHandler, self).__init__(
571 566 shell=shell, prefilter_manager=prefilter_manager, config=config
572 567 )
573 568 self.prefilter_manager.register_handler(
574 569 self.handler_name,
575 570 self,
576 571 self.esc_strings
577 572 )
578 573
579 574 def handle(self, line_info):
580 575 # print "normal: ", line_info
581 576 """Handle normal input lines. Use as a template for handlers."""
582 577
583 578 # With autoindent on, we need some way to exit the input loop, and I
584 579 # don't want to force the user to have to backspace all the way to
585 580 # clear the line. The rule will be in this case, that either two
586 581 # lines of pure whitespace in a row, or a line of pure whitespace but
587 582 # of a size different to the indent level, will exit the input loop.
588 583 line = line_info.line
589 584 continue_prompt = line_info.continue_prompt
590 585
591 586 if (continue_prompt and
592 587 self.shell.autoindent and
593 588 line.isspace() and
594 589 0 < abs(len(line) - self.shell.indent_current_nsp) <= 2):
595 590 line = ''
596 591
597 592 return line
598 593
599 594 def __str__(self):
600 595 return "<%s(name=%s)>" % (self.__class__.__name__, self.handler_name)
601 596
602 597
603 598 class AliasHandler(PrefilterHandler):
604 599
605 600 handler_name = Unicode('alias')
606 601
607 602 def handle(self, line_info):
608 603 """Handle alias input lines. """
609 604 transformed = self.shell.alias_manager.expand_aliases(line_info.ifun,line_info.the_rest)
610 605 # pre is needed, because it carries the leading whitespace. Otherwise
611 606 # aliases won't work in indented sections.
612 607 line_out = '%sget_ipython().system(%r)' % (line_info.pre_whitespace, transformed)
613 608
614 609 return line_out
615 610
616 611
617 612 class MacroHandler(PrefilterHandler):
618 613 handler_name = Unicode("macro")
619 614
620 615 def handle(self, line_info):
621 616 obj = self.shell.user_ns.get(line_info.ifun)
622 617 pre_space = line_info.pre_whitespace
623 618 line_sep = "\n" + pre_space
624 619 return pre_space + line_sep.join(obj.value.splitlines())
625 620
626 621
627 622 class MagicHandler(PrefilterHandler):
628 623
629 624 handler_name = Unicode('magic')
630 625 esc_strings = List([ESC_MAGIC])
631 626
632 627 def handle(self, line_info):
633 628 """Execute magic functions."""
634 629 ifun = line_info.ifun
635 630 the_rest = line_info.the_rest
636 631 cmd = '%sget_ipython().magic(%r)' % (line_info.pre_whitespace,
637 632 (ifun + " " + the_rest))
638 633 return cmd
639 634
640 635
641 636 class AutoHandler(PrefilterHandler):
642 637
643 638 handler_name = Unicode('auto')
644 639 esc_strings = List([ESC_PAREN, ESC_QUOTE, ESC_QUOTE2])
645 640
646 641 def handle(self, line_info):
647 642 """Handle lines which can be auto-executed, quoting if requested."""
648 643 line = line_info.line
649 644 ifun = line_info.ifun
650 645 the_rest = line_info.the_rest
651 646 pre = line_info.pre
652 647 esc = line_info.esc
653 648 continue_prompt = line_info.continue_prompt
654 649 obj = line_info.ofind(self.shell)['obj']
655 650 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun,the_rest) # dbg
656 651
657 652 # This should only be active for single-line input!
658 653 if continue_prompt:
659 654 return line
660 655
661 656 force_auto = isinstance(obj, IPyAutocall)
662 657
663 658 # User objects sometimes raise exceptions on attribute access other
664 659 # than AttributeError (we've seen it in the past), so it's safest to be
665 660 # ultra-conservative here and catch all.
666 661 try:
667 662 auto_rewrite = obj.rewrite
668 663 except Exception:
669 664 auto_rewrite = True
670 665
671 666 if esc == ESC_QUOTE:
672 667 # Auto-quote splitting on whitespace
673 668 newcmd = '%s("%s")' % (ifun,'", "'.join(the_rest.split()) )
674 669 elif esc == ESC_QUOTE2:
675 670 # Auto-quote whole string
676 671 newcmd = '%s("%s")' % (ifun,the_rest)
677 672 elif esc == ESC_PAREN:
678 673 newcmd = '%s(%s)' % (ifun,",".join(the_rest.split()))
679 674 else:
680 675 # Auto-paren.
681 676 if force_auto:
682 677 # Don't rewrite if it is already a call.
683 678 do_rewrite = not the_rest.startswith('(')
684 679 else:
685 680 if not the_rest:
686 681 # We only apply it to argument-less calls if the autocall
687 682 # parameter is set to 2.
688 683 do_rewrite = (self.shell.autocall >= 2)
689 684 elif the_rest.startswith('[') and hasattr(obj, '__getitem__'):
690 685 # Don't autocall in this case: item access for an object
691 686 # which is BOTH callable and implements __getitem__.
692 687 do_rewrite = False
693 688 else:
694 689 do_rewrite = True
695 690
696 691 # Figure out the rewritten command
697 692 if do_rewrite:
698 693 if the_rest.endswith(';'):
699 694 newcmd = '%s(%s);' % (ifun.rstrip(),the_rest[:-1])
700 695 else:
701 696 newcmd = '%s(%s)' % (ifun.rstrip(), the_rest)
702 697 else:
703 698 normal_handler = self.prefilter_manager.get_handler_by_name('normal')
704 699 return normal_handler.handle(line_info)
705 700
706 701 # Display the rewritten call
707 702 if auto_rewrite:
708 703 self.shell.auto_rewrite_input(newcmd)
709 704
710 705 return newcmd
711 706
712 707
713 708 class EmacsHandler(PrefilterHandler):
714 709
715 710 handler_name = Unicode('emacs')
716 711 esc_strings = List([])
717 712
718 713 def handle(self, line_info):
719 714 """Handle input lines marked by python-mode."""
720 715
721 716 # Currently, nothing is done. Later more functionality can be added
722 717 # here if needed.
723 718
724 719 # The input cache shouldn't be updated
725 720 return line_info.line
726 721
727 722
728 723 #-----------------------------------------------------------------------------
729 724 # Defaults
730 725 #-----------------------------------------------------------------------------
731 726
732 727
733 728 _default_transformers = [
734 729 ]
735 730
736 731 _default_checkers = [
737 732 EmacsChecker,
738 733 MacroChecker,
739 734 IPyAutocallChecker,
740 735 AssignmentChecker,
741 736 AutoMagicChecker,
742 737 AliasChecker,
743 738 PythonOpsChecker,
744 739 AutocallChecker
745 740 ]
746 741
747 742 _default_handlers = [
748 743 PrefilterHandler,
749 744 AliasHandler,
750 745 MacroHandler,
751 746 MagicHandler,
752 747 AutoHandler,
753 748 EmacsHandler
754 749 ]
@@ -1,307 +1,306 b''
1 1 # encoding: utf-8
2 2 """
3 3 An application for managing IPython profiles.
4 4
5 5 To be invoked as the `ipython profile` subcommand.
6 6
7 7 Authors:
8 8
9 9 * Min RK
10 10
11 11 """
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Copyright (C) 2008-2011 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-----------------------------------------------------------------------------
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Imports
22 22 #-----------------------------------------------------------------------------
23 23
24 import logging
25 24 import os
26 25
27 from IPython.config.application import Application, boolean_flag
26 from IPython.config.application import Application
28 27 from IPython.core.application import (
29 BaseIPythonApplication, base_flags, base_aliases
28 BaseIPythonApplication, base_flags
30 29 )
31 30 from IPython.core.profiledir import ProfileDir
32 31 from IPython.utils.path import get_ipython_dir, get_ipython_package_dir
33 32 from IPython.utils.traitlets import Unicode, Bool, Dict
34 33
35 34 #-----------------------------------------------------------------------------
36 35 # Constants
37 36 #-----------------------------------------------------------------------------
38 37
39 38 create_help = """Create an IPython profile by name
40 39
41 40 Create an ipython profile directory by its name or
42 41 profile directory path. Profile directories contain
43 42 configuration, log and security related files and are named
44 43 using the convention 'profile_<name>'. By default they are
45 44 located in your ipython directory. Once created, you will
46 45 can edit the configuration files in the profile
47 46 directory to configure IPython. Most users will create a
48 47 profile directory by name,
49 48 `ipython profile create myprofile`, which will put the directory
50 49 in `<ipython_dir>/profile_myprofile`.
51 50 """
52 51 list_help = """List available IPython profiles
53 52
54 53 List all available profiles, by profile location, that can
55 54 be found in the current working directly or in the ipython
56 55 directory. Profile directories are named using the convention
57 56 'profile_<profile>'.
58 57 """
59 58 profile_help = """Manage IPython profiles
60 59
61 60 Profile directories contain
62 61 configuration, log and security related files and are named
63 62 using the convention 'profile_<name>'. By default they are
64 63 located in your ipython directory. You can create profiles
65 64 with `ipython profile create <name>`, or see the profiles you
66 65 already have with `ipython profile list`
67 66
68 67 To get started configuring IPython, simply do:
69 68
70 69 $> ipython profile create
71 70
72 71 and IPython will create the default profile in <ipython_dir>/profile_default,
73 72 where you can edit ipython_config.py to start configuring IPython.
74 73
75 74 """
76 75
77 76 _list_examples = "ipython profile list # list all profiles"
78 77
79 78 _create_examples = """
80 79 ipython profile create foo # create profile foo w/ default config files
81 80 ipython profile create foo --reset # restage default config files over current
82 81 ipython profile create foo --parallel # also stage parallel config files
83 82 """
84 83
85 84 _main_examples = """
86 85 ipython profile create -h # show the help string for the create subcommand
87 86 ipython profile list -h # show the help string for the list subcommand
88 87
89 88 ipython locate profile foo # print the path to the directory for profile 'foo'
90 89 """
91 90
92 91 #-----------------------------------------------------------------------------
93 92 # Profile Application Class (for `ipython profile` subcommand)
94 93 #-----------------------------------------------------------------------------
95 94
96 95
97 96 def list_profiles_in(path):
98 97 """list profiles in a given root directory"""
99 98 files = os.listdir(path)
100 99 profiles = []
101 100 for f in files:
102 101 full_path = os.path.join(path, f)
103 102 if os.path.isdir(full_path) and f.startswith('profile_'):
104 103 profiles.append(f.split('_',1)[-1])
105 104 return profiles
106 105
107 106
108 107 def list_bundled_profiles():
109 108 """list profiles that are bundled with IPython."""
110 109 path = os.path.join(get_ipython_package_dir(), u'config', u'profile')
111 110 files = os.listdir(path)
112 111 profiles = []
113 112 for profile in files:
114 113 full_path = os.path.join(path, profile)
115 114 if os.path.isdir(full_path) and profile != "__pycache__":
116 115 profiles.append(profile)
117 116 return profiles
118 117
119 118
120 119 class ProfileLocate(BaseIPythonApplication):
121 120 description = """print the path an IPython profile dir"""
122 121
123 122 def parse_command_line(self, argv=None):
124 123 super(ProfileLocate, self).parse_command_line(argv)
125 124 if self.extra_args:
126 125 self.profile = self.extra_args[0]
127 126
128 127 def start(self):
129 128 print self.profile_dir.location
130 129
131 130
132 131 class ProfileList(Application):
133 132 name = u'ipython-profile'
134 133 description = list_help
135 134 examples = _list_examples
136 135
137 136 aliases = Dict({
138 137 'ipython-dir' : 'ProfileList.ipython_dir',
139 138 'log-level' : 'Application.log_level',
140 139 })
141 140 flags = Dict(dict(
142 141 debug = ({'Application' : {'log_level' : 0}},
143 142 "Set Application.log_level to 0, maximizing log output."
144 143 )
145 144 ))
146 145
147 146 ipython_dir = Unicode(get_ipython_dir(), config=True,
148 147 help="""
149 148 The name of the IPython directory. This directory is used for logging
150 149 configuration (through profiles), history storage, etc. The default
151 150 is usually $HOME/.ipython. This options can also be specified through
152 151 the environment variable IPYTHONDIR.
153 152 """
154 153 )
155 154
156 155
157 156 def _print_profiles(self, profiles):
158 157 """print list of profiles, indented."""
159 158 for profile in profiles:
160 159 print ' %s' % profile
161 160
162 161 def list_profile_dirs(self):
163 162 profiles = list_bundled_profiles()
164 163 if profiles:
165 164 print
166 165 print "Available profiles in IPython:"
167 166 self._print_profiles(profiles)
168 167 print
169 168 print " The first request for a bundled profile will copy it"
170 169 print " into your IPython directory (%s)," % self.ipython_dir
171 170 print " where you can customize it."
172 171
173 172 profiles = list_profiles_in(self.ipython_dir)
174 173 if profiles:
175 174 print
176 175 print "Available profiles in %s:" % self.ipython_dir
177 176 self._print_profiles(profiles)
178 177
179 178 profiles = list_profiles_in(os.getcwdu())
180 179 if profiles:
181 180 print
182 181 print "Available profiles in current directory (%s):" % os.getcwdu()
183 182 self._print_profiles(profiles)
184 183
185 184 print
186 185 print "To use any of the above profiles, start IPython with:"
187 186 print " ipython --profile=<name>"
188 187 print
189 188
190 189 def start(self):
191 190 self.list_profile_dirs()
192 191
193 192
194 193 create_flags = {}
195 194 create_flags.update(base_flags)
196 195 # don't include '--init' flag, which implies running profile create in other apps
197 196 create_flags.pop('init')
198 197 create_flags['reset'] = ({'ProfileCreate': {'overwrite' : True}},
199 198 "reset config files in this profile to the defaults.")
200 199 create_flags['parallel'] = ({'ProfileCreate': {'parallel' : True}},
201 200 "Include the config files for parallel "
202 201 "computing apps (ipengine, ipcontroller, etc.)")
203 202
204 203
205 204 class ProfileCreate(BaseIPythonApplication):
206 205 name = u'ipython-profile'
207 206 description = create_help
208 207 examples = _create_examples
209 208 auto_create = Bool(True, config=False)
210 209
211 210 def _copy_config_files_default(self):
212 211 return True
213 212
214 213 parallel = Bool(False, config=True,
215 214 help="whether to include parallel computing config files")
216 215 def _parallel_changed(self, name, old, new):
217 216 parallel_files = [ 'ipcontroller_config.py',
218 217 'ipengine_config.py',
219 218 'ipcluster_config.py'
220 219 ]
221 220 if new:
222 221 for cf in parallel_files:
223 222 self.config_files.append(cf)
224 223 else:
225 224 for cf in parallel_files:
226 225 if cf in self.config_files:
227 226 self.config_files.remove(cf)
228 227
229 228 def parse_command_line(self, argv):
230 229 super(ProfileCreate, self).parse_command_line(argv)
231 230 # accept positional arg as profile name
232 231 if self.extra_args:
233 232 self.profile = self.extra_args[0]
234 233
235 234 flags = Dict(create_flags)
236 235
237 236 classes = [ProfileDir]
238 237
239 238 def init_config_files(self):
240 239 super(ProfileCreate, self).init_config_files()
241 240 # use local imports, since these classes may import from here
242 241 from IPython.frontend.terminal.ipapp import TerminalIPythonApp
243 242 apps = [TerminalIPythonApp]
244 243 try:
245 244 from IPython.frontend.qt.console.qtconsoleapp import IPythonQtConsoleApp
246 245 except Exception:
247 246 # this should be ImportError, but under weird circumstances
248 247 # this might be an AttributeError, or possibly others
249 248 # in any case, nothing should cause the profile creation to crash.
250 249 pass
251 250 else:
252 251 apps.append(IPythonQtConsoleApp)
253 252 try:
254 253 from IPython.frontend.html.notebook.notebookapp import NotebookApp
255 254 except ImportError:
256 255 pass
257 256 except Exception:
258 257 self.log.debug('Unexpected error when importing NotebookApp',
259 258 exc_info=True
260 259 )
261 260 else:
262 261 apps.append(NotebookApp)
263 262 if self.parallel:
264 263 from IPython.parallel.apps.ipcontrollerapp import IPControllerApp
265 264 from IPython.parallel.apps.ipengineapp import IPEngineApp
266 265 from IPython.parallel.apps.ipclusterapp import IPClusterStart
267 266 from IPython.parallel.apps.iploggerapp import IPLoggerApp
268 267 apps.extend([
269 268 IPControllerApp,
270 269 IPEngineApp,
271 270 IPClusterStart,
272 271 IPLoggerApp,
273 272 ])
274 273 for App in apps:
275 274 app = App()
276 275 app.config.update(self.config)
277 276 app.log = self.log
278 277 app.overwrite = self.overwrite
279 278 app.copy_config_files=True
280 279 app.profile = self.profile
281 280 app.init_profile_dir()
282 281 app.init_config_files()
283 282
284 283 def stage_default_config_file(self):
285 284 pass
286 285
287 286
288 287 class ProfileApp(Application):
289 288 name = u'ipython-profile'
290 289 description = profile_help
291 290 examples = _main_examples
292 291
293 292 subcommands = Dict(dict(
294 293 create = (ProfileCreate, ProfileCreate.description.splitlines()[0]),
295 294 list = (ProfileList, ProfileList.description.splitlines()[0]),
296 295 ))
297 296
298 297 def start(self):
299 298 if self.subapp is None:
300 299 print "No subcommand specified. Must specify one of: %s"%(self.subcommands.keys())
301 300 print
302 301 self.print_description()
303 302 self.print_subcommands()
304 303 self.exit(1)
305 304 else:
306 305 return self.subapp.start()
307 306
@@ -1,228 +1,226 b''
1 1 # encoding: utf-8
2 2 """
3 3 An object for managing IPython profile directories.
4 4
5 5 Authors:
6 6
7 7 * Brian Granger
8 8 * Fernando Perez
9 9 * Min RK
10 10
11 11 """
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Copyright (C) 2008-2011 The IPython Development Team
15 15 #
16 16 # Distributed under the terms of the BSD License. The full license is in
17 17 # the file COPYING, distributed as part of this software.
18 18 #-----------------------------------------------------------------------------
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Imports
22 22 #-----------------------------------------------------------------------------
23 23
24 24 import os
25 25 import shutil
26 import sys
27 26
28 27 from IPython.config.configurable import LoggingConfigurable
29 from IPython.config.loader import Config
30 28 from IPython.utils.path import get_ipython_package_dir, expand_path
31 from IPython.utils.traitlets import List, Unicode, Bool
29 from IPython.utils.traitlets import Unicode, Bool
32 30
33 31 #-----------------------------------------------------------------------------
34 32 # Classes and functions
35 33 #-----------------------------------------------------------------------------
36 34
37 35
38 36 #-----------------------------------------------------------------------------
39 37 # Module errors
40 38 #-----------------------------------------------------------------------------
41 39
42 40 class ProfileDirError(Exception):
43 41 pass
44 42
45 43
46 44 #-----------------------------------------------------------------------------
47 45 # Class for managing profile directories
48 46 #-----------------------------------------------------------------------------
49 47
50 48 class ProfileDir(LoggingConfigurable):
51 49 """An object to manage the profile directory and its resources.
52 50
53 51 The profile directory is used by all IPython applications, to manage
54 52 configuration, logging and security.
55 53
56 54 This object knows how to find, create and manage these directories. This
57 55 should be used by any code that wants to handle profiles.
58 56 """
59 57
60 58 security_dir_name = Unicode('security')
61 59 log_dir_name = Unicode('log')
62 60 startup_dir_name = Unicode('startup')
63 61 pid_dir_name = Unicode('pid')
64 62 security_dir = Unicode(u'')
65 63 log_dir = Unicode(u'')
66 64 startup_dir = Unicode(u'')
67 65 pid_dir = Unicode(u'')
68 66
69 67 location = Unicode(u'', config=True,
70 68 help="""Set the profile location directly. This overrides the logic used by the
71 69 `profile` option.""",
72 70 )
73 71
74 72 _location_isset = Bool(False) # flag for detecting multiply set location
75 73
76 74 def _location_changed(self, name, old, new):
77 75 if self._location_isset:
78 76 raise RuntimeError("Cannot set profile location more than once.")
79 77 self._location_isset = True
80 78 if not os.path.isdir(new):
81 79 os.makedirs(new)
82 80
83 81 # ensure config files exist:
84 82 self.security_dir = os.path.join(new, self.security_dir_name)
85 83 self.log_dir = os.path.join(new, self.log_dir_name)
86 84 self.startup_dir = os.path.join(new, self.startup_dir_name)
87 85 self.pid_dir = os.path.join(new, self.pid_dir_name)
88 86 self.check_dirs()
89 87
90 88 def _log_dir_changed(self, name, old, new):
91 89 self.check_log_dir()
92 90
93 91 def check_log_dir(self):
94 92 if not os.path.isdir(self.log_dir):
95 93 os.mkdir(self.log_dir)
96 94
97 95 def _startup_dir_changed(self, name, old, new):
98 96 self.check_startup_dir()
99 97
100 98 def check_startup_dir(self):
101 99 if not os.path.isdir(self.startup_dir):
102 100 os.mkdir(self.startup_dir)
103 101 readme = os.path.join(self.startup_dir, 'README')
104 102 src = os.path.join(get_ipython_package_dir(), u'config', u'profile', u'README_STARTUP')
105 103 if not os.path.exists(readme):
106 104 shutil.copy(src, readme)
107 105
108 106 def _security_dir_changed(self, name, old, new):
109 107 self.check_security_dir()
110 108
111 109 def check_security_dir(self):
112 110 if not os.path.isdir(self.security_dir):
113 111 os.mkdir(self.security_dir, 0o700)
114 112 else:
115 113 try:
116 114 os.chmod(self.security_dir, 0o700)
117 115 except OSError:
118 116 self.log.warn("Could not set security dir permissions to private.")
119 117
120 118 def _pid_dir_changed(self, name, old, new):
121 119 self.check_pid_dir()
122 120
123 121 def check_pid_dir(self):
124 122 if not os.path.isdir(self.pid_dir):
125 123 os.mkdir(self.pid_dir, 0o700)
126 124 else:
127 125 try:
128 126 os.chmod(self.pid_dir, 0o700)
129 127 except OSError:
130 128 self.log.warn("Could not set pid dir permissions to private.")
131 129
132 130 def check_dirs(self):
133 131 self.check_security_dir()
134 132 self.check_log_dir()
135 133 self.check_pid_dir()
136 134 self.check_startup_dir()
137 135
138 136 def copy_config_file(self, config_file, path=None, overwrite=False):
139 137 """Copy a default config file into the active profile directory.
140 138
141 139 Default configuration files are kept in :mod:`IPython.config.default`.
142 140 This function moves these from that location to the working profile
143 141 directory.
144 142 """
145 143 dst = os.path.join(self.location, config_file)
146 144 if os.path.isfile(dst) and not overwrite:
147 145 return False
148 146 if path is None:
149 147 path = os.path.join(get_ipython_package_dir(), u'config', u'profile', u'default')
150 148 src = os.path.join(path, config_file)
151 149 shutil.copy(src, dst)
152 150 return True
153 151
154 152 @classmethod
155 153 def create_profile_dir(cls, profile_dir, config=None):
156 154 """Create a new profile directory given a full path.
157 155
158 156 Parameters
159 157 ----------
160 158 profile_dir : str
161 159 The full path to the profile directory. If it does exist, it will
162 160 be used. If not, it will be created.
163 161 """
164 162 return cls(location=profile_dir, config=config)
165 163
166 164 @classmethod
167 165 def create_profile_dir_by_name(cls, path, name=u'default', config=None):
168 166 """Create a profile dir by profile name and path.
169 167
170 168 Parameters
171 169 ----------
172 170 path : unicode
173 171 The path (directory) to put the profile directory in.
174 172 name : unicode
175 173 The name of the profile. The name of the profile directory will
176 174 be "profile_<profile>".
177 175 """
178 176 if not os.path.isdir(path):
179 177 raise ProfileDirError('Directory not found: %s' % path)
180 178 profile_dir = os.path.join(path, u'profile_' + name)
181 179 return cls(location=profile_dir, config=config)
182 180
183 181 @classmethod
184 182 def find_profile_dir_by_name(cls, ipython_dir, name=u'default', config=None):
185 183 """Find an existing profile dir by profile name, return its ProfileDir.
186 184
187 185 This searches through a sequence of paths for a profile dir. If it
188 186 is not found, a :class:`ProfileDirError` exception will be raised.
189 187
190 188 The search path algorithm is:
191 189 1. ``os.getcwdu()``
192 190 2. ``ipython_dir``
193 191
194 192 Parameters
195 193 ----------
196 194 ipython_dir : unicode or str
197 195 The IPython directory to use.
198 196 name : unicode or str
199 197 The name of the profile. The name of the profile directory
200 198 will be "profile_<profile>".
201 199 """
202 200 dirname = u'profile_' + name
203 201 paths = [os.getcwdu(), ipython_dir]
204 202 for p in paths:
205 203 profile_dir = os.path.join(p, dirname)
206 204 if os.path.isdir(profile_dir):
207 205 return cls(location=profile_dir, config=config)
208 206 else:
209 207 raise ProfileDirError('Profile directory not found in paths: %s' % dirname)
210 208
211 209 @classmethod
212 210 def find_profile_dir(cls, profile_dir, config=None):
213 211 """Find/create a profile dir and return its ProfileDir.
214 212
215 213 This will create the profile directory if it doesn't exist.
216 214
217 215 Parameters
218 216 ----------
219 217 profile_dir : unicode or str
220 218 The path of the profile directory. This is expanded using
221 219 :func:`IPython.utils.genutils.expand_path`.
222 220 """
223 221 profile_dir = expand_path(profile_dir)
224 222 if not os.path.isdir(profile_dir):
225 223 raise ProfileDirError('Profile directory not found: %s' % profile_dir)
226 224 return cls(location=profile_dir, config=config)
227 225
228 226
@@ -1,1247 +1,1246 b''
1 1 # -*- coding: utf-8 -*-
2 2 """
3 3 ultratb.py -- Spice up your tracebacks!
4 4
5 5 * ColorTB
6 6 I've always found it a bit hard to visually parse tracebacks in Python. The
7 7 ColorTB class is a solution to that problem. It colors the different parts of a
8 8 traceback in a manner similar to what you would expect from a syntax-highlighting
9 9 text editor.
10 10
11 11 Installation instructions for ColorTB:
12 12 import sys,ultratb
13 13 sys.excepthook = ultratb.ColorTB()
14 14
15 15 * VerboseTB
16 16 I've also included a port of Ka-Ping Yee's "cgitb.py" that produces all kinds
17 17 of useful info when a traceback occurs. Ping originally had it spit out HTML
18 18 and intended it for CGI programmers, but why should they have all the fun? I
19 19 altered it to spit out colored text to the terminal. It's a bit overwhelming,
20 20 but kind of neat, and maybe useful for long-running programs that you believe
21 21 are bug-free. If a crash *does* occur in that type of program you want details.
22 22 Give it a shot--you'll love it or you'll hate it.
23 23
24 24 Note:
25 25
26 26 The Verbose mode prints the variables currently visible where the exception
27 27 happened (shortening their strings if too long). This can potentially be
28 28 very slow, if you happen to have a huge data structure whose string
29 29 representation is complex to compute. Your computer may appear to freeze for
30 30 a while with cpu usage at 100%. If this occurs, you can cancel the traceback
31 31 with Ctrl-C (maybe hitting it more than once).
32 32
33 33 If you encounter this kind of situation often, you may want to use the
34 34 Verbose_novars mode instead of the regular Verbose, which avoids formatting
35 35 variables (but otherwise includes the information and context given by
36 36 Verbose).
37 37
38 38
39 39 Installation instructions for ColorTB:
40 40 import sys,ultratb
41 41 sys.excepthook = ultratb.VerboseTB()
42 42
43 43 Note: Much of the code in this module was lifted verbatim from the standard
44 44 library module 'traceback.py' and Ka-Ping Yee's 'cgitb.py'.
45 45
46 46 * Color schemes
47 47 The colors are defined in the class TBTools through the use of the
48 48 ColorSchemeTable class. Currently the following exist:
49 49
50 50 - NoColor: allows all of this module to be used in any terminal (the color
51 51 escapes are just dummy blank strings).
52 52
53 53 - Linux: is meant to look good in a terminal like the Linux console (black
54 54 or very dark background).
55 55
56 56 - LightBG: similar to Linux but swaps dark/light colors to be more readable
57 57 in light background terminals.
58 58
59 59 You can implement other color schemes easily, the syntax is fairly
60 60 self-explanatory. Please send back new schemes you develop to the author for
61 61 possible inclusion in future releases.
62 62
63 63 Inheritance diagram:
64 64
65 65 .. inheritance-diagram:: IPython.core.ultratb
66 66 :parts: 3
67 67 """
68 68
69 69 #*****************************************************************************
70 70 # Copyright (C) 2001 Nathaniel Gray <n8gray@caltech.edu>
71 71 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
72 72 #
73 73 # Distributed under the terms of the BSD License. The full license is in
74 74 # the file COPYING, distributed as part of this software.
75 75 #*****************************************************************************
76 76
77 77 from __future__ import unicode_literals
78 78
79 79 import inspect
80 80 import keyword
81 81 import linecache
82 82 import os
83 83 import pydoc
84 84 import re
85 85 import sys
86 86 import time
87 87 import tokenize
88 88 import traceback
89 89 import types
90 90
91 91 try: # Python 2
92 92 generate_tokens = tokenize.generate_tokens
93 93 except AttributeError: # Python 3
94 94 generate_tokens = tokenize.tokenize
95 95
96 96 # For purposes of monkeypatching inspect to fix a bug in it.
97 97 from inspect import getsourcefile, getfile, getmodule,\
98 98 ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode
99 99
100 100 # IPython's own modules
101 101 # Modified pdb which doesn't damage IPython's readline handling
102 102 from IPython.core import debugger, ipapi
103 103 from IPython.core.display_trap import DisplayTrap
104 104 from IPython.core.excolors import exception_colors
105 105 from IPython.utils import PyColorize
106 106 from IPython.utils import io
107 107 from IPython.utils import path as util_path
108 108 from IPython.utils import py3compat
109 109 from IPython.utils import pyfile
110 110 from IPython.utils import ulinecache
111 111 from IPython.utils.data import uniq_stable
112 from IPython.utils.openpy import read_py_file
113 112 from IPython.utils.warn import info, error
114 113
115 114 # Globals
116 115 # amount of space to put line numbers before verbose tracebacks
117 116 INDENT_SIZE = 8
118 117
119 118 # Default color scheme. This is used, for example, by the traceback
120 119 # formatter. When running in an actual IPython instance, the user's rc.colors
121 120 # value is used, but havinga module global makes this functionality available
122 121 # to users of ultratb who are NOT running inside ipython.
123 122 DEFAULT_SCHEME = 'NoColor'
124 123
125 124 #---------------------------------------------------------------------------
126 125 # Code begins
127 126
128 127 # Utility functions
129 128 def inspect_error():
130 129 """Print a message about internal inspect errors.
131 130
132 131 These are unfortunately quite common."""
133 132
134 133 error('Internal Python error in the inspect module.\n'
135 134 'Below is the traceback from this internal error.\n')
136 135
137 136 # This function is a monkeypatch we apply to the Python inspect module. We have
138 137 # now found when it's needed (see discussion on issue gh-1456), and we have a
139 138 # test case (IPython.core.tests.test_ultratb.ChangedPyFileTest) that fails if
140 139 # the monkeypatch is not applied. TK, Aug 2012.
141 140 def findsource(object):
142 141 """Return the entire source file and starting line number for an object.
143 142
144 143 The argument may be a module, class, method, function, traceback, frame,
145 144 or code object. The source code is returned as a list of all the lines
146 145 in the file and the line number indexes a line in that list. An IOError
147 146 is raised if the source code cannot be retrieved.
148 147
149 148 FIXED version with which we monkeypatch the stdlib to work around a bug."""
150 149
151 150 file = getsourcefile(object) or getfile(object)
152 151 # If the object is a frame, then trying to get the globals dict from its
153 152 # module won't work. Instead, the frame object itself has the globals
154 153 # dictionary.
155 154 globals_dict = None
156 155 if inspect.isframe(object):
157 156 # XXX: can this ever be false?
158 157 globals_dict = object.f_globals
159 158 else:
160 159 module = getmodule(object, file)
161 160 if module:
162 161 globals_dict = module.__dict__
163 162 lines = linecache.getlines(file, globals_dict)
164 163 if not lines:
165 164 raise IOError('could not get source code')
166 165
167 166 if ismodule(object):
168 167 return lines, 0
169 168
170 169 if isclass(object):
171 170 name = object.__name__
172 171 pat = re.compile(r'^(\s*)class\s*' + name + r'\b')
173 172 # make some effort to find the best matching class definition:
174 173 # use the one with the least indentation, which is the one
175 174 # that's most probably not inside a function definition.
176 175 candidates = []
177 176 for i in range(len(lines)):
178 177 match = pat.match(lines[i])
179 178 if match:
180 179 # if it's at toplevel, it's already the best one
181 180 if lines[i][0] == 'c':
182 181 return lines, i
183 182 # else add whitespace to candidate list
184 183 candidates.append((match.group(1), i))
185 184 if candidates:
186 185 # this will sort by whitespace, and by line number,
187 186 # less whitespace first
188 187 candidates.sort()
189 188 return lines, candidates[0][1]
190 189 else:
191 190 raise IOError('could not find class definition')
192 191
193 192 if ismethod(object):
194 193 object = object.im_func
195 194 if isfunction(object):
196 195 object = object.func_code
197 196 if istraceback(object):
198 197 object = object.tb_frame
199 198 if isframe(object):
200 199 object = object.f_code
201 200 if iscode(object):
202 201 if not hasattr(object, 'co_firstlineno'):
203 202 raise IOError('could not find function definition')
204 203 pat = re.compile(r'^(\s*def\s)|(.*(?<!\w)lambda(:|\s))|^(\s*@)')
205 204 pmatch = pat.match
206 205 # fperez - fix: sometimes, co_firstlineno can give a number larger than
207 206 # the length of lines, which causes an error. Safeguard against that.
208 207 lnum = min(object.co_firstlineno,len(lines))-1
209 208 while lnum > 0:
210 209 if pmatch(lines[lnum]): break
211 210 lnum -= 1
212 211
213 212 return lines, lnum
214 213 raise IOError('could not find code object')
215 214
216 215 # Monkeypatch inspect to apply our bugfix. This code only works with Python >= 2.5
217 216 inspect.findsource = findsource
218 217
219 218 def fix_frame_records_filenames(records):
220 219 """Try to fix the filenames in each record from inspect.getinnerframes().
221 220
222 221 Particularly, modules loaded from within zip files have useless filenames
223 222 attached to their code object, and inspect.getinnerframes() just uses it.
224 223 """
225 224 fixed_records = []
226 225 for frame, filename, line_no, func_name, lines, index in records:
227 226 # Look inside the frame's globals dictionary for __file__, which should
228 227 # be better.
229 228 better_fn = frame.f_globals.get('__file__', None)
230 229 if isinstance(better_fn, str):
231 230 # Check the type just in case someone did something weird with
232 231 # __file__. It might also be None if the error occurred during
233 232 # import.
234 233 filename = better_fn
235 234 fixed_records.append((frame, filename, line_no, func_name, lines, index))
236 235 return fixed_records
237 236
238 237
239 238 def _fixed_getinnerframes(etb, context=1,tb_offset=0):
240 239 LNUM_POS, LINES_POS, INDEX_POS = 2, 4, 5
241 240
242 241 records = fix_frame_records_filenames(inspect.getinnerframes(etb, context))
243 242
244 243 # If the error is at the console, don't build any context, since it would
245 244 # otherwise produce 5 blank lines printed out (there is no file at the
246 245 # console)
247 246 rec_check = records[tb_offset:]
248 247 try:
249 248 rname = rec_check[0][1]
250 249 if rname == '<ipython console>' or rname.endswith('<string>'):
251 250 return rec_check
252 251 except IndexError:
253 252 pass
254 253
255 254 aux = traceback.extract_tb(etb)
256 255 assert len(records) == len(aux)
257 256 for i, (file, lnum, _, _) in zip(range(len(records)), aux):
258 257 maybeStart = lnum-1 - context//2
259 258 start = max(maybeStart, 0)
260 259 end = start + context
261 260 lines = ulinecache.getlines(file)[start:end]
262 261 buf = list(records[i])
263 262 buf[LNUM_POS] = lnum
264 263 buf[INDEX_POS] = lnum - 1 - start
265 264 buf[LINES_POS] = lines
266 265 records[i] = tuple(buf)
267 266 return records[tb_offset:]
268 267
269 268 # Helper function -- largely belongs to VerboseTB, but we need the same
270 269 # functionality to produce a pseudo verbose TB for SyntaxErrors, so that they
271 270 # can be recognized properly by ipython.el's py-traceback-line-re
272 271 # (SyntaxErrors have to be treated specially because they have no traceback)
273 272
274 273 _parser = PyColorize.Parser()
275 274
276 275 def _format_traceback_lines(lnum, index, lines, Colors, lvals=None,scheme=None):
277 276 numbers_width = INDENT_SIZE - 1
278 277 res = []
279 278 i = lnum - index
280 279
281 280 # This lets us get fully syntax-highlighted tracebacks.
282 281 if scheme is None:
283 282 ipinst = ipapi.get()
284 283 if ipinst is not None:
285 284 scheme = ipinst.colors
286 285 else:
287 286 scheme = DEFAULT_SCHEME
288 287
289 288 _line_format = _parser.format2
290 289
291 290 for line in lines:
292 291 line = py3compat.cast_unicode(line)
293 292
294 293 new_line, err = _line_format(line, 'str', scheme)
295 294 if not err: line = new_line
296 295
297 296 if i == lnum:
298 297 # This is the line with the error
299 298 pad = numbers_width - len(str(i))
300 299 if pad >= 3:
301 300 marker = '-'*(pad-3) + '-> '
302 301 elif pad == 2:
303 302 marker = '> '
304 303 elif pad == 1:
305 304 marker = '>'
306 305 else:
307 306 marker = ''
308 307 num = marker + str(i)
309 308 line = '%s%s%s %s%s' %(Colors.linenoEm, num,
310 309 Colors.line, line, Colors.Normal)
311 310 else:
312 311 num = '%*s' % (numbers_width,i)
313 312 line = '%s%s%s %s' %(Colors.lineno, num,
314 313 Colors.Normal, line)
315 314
316 315 res.append(line)
317 316 if lvals and i == lnum:
318 317 res.append(lvals + '\n')
319 318 i = i + 1
320 319 return res
321 320
322 321
323 322 #---------------------------------------------------------------------------
324 323 # Module classes
325 324 class TBTools(object):
326 325 """Basic tools used by all traceback printer classes."""
327 326
328 327 # Number of frames to skip when reporting tracebacks
329 328 tb_offset = 0
330 329
331 330 def __init__(self, color_scheme='NoColor', call_pdb=False, ostream=None):
332 331 # Whether to call the interactive pdb debugger after printing
333 332 # tracebacks or not
334 333 self.call_pdb = call_pdb
335 334
336 335 # Output stream to write to. Note that we store the original value in
337 336 # a private attribute and then make the public ostream a property, so
338 337 # that we can delay accessing io.stdout until runtime. The way
339 338 # things are written now, the io.stdout object is dynamically managed
340 339 # so a reference to it should NEVER be stored statically. This
341 340 # property approach confines this detail to a single location, and all
342 341 # subclasses can simply access self.ostream for writing.
343 342 self._ostream = ostream
344 343
345 344 # Create color table
346 345 self.color_scheme_table = exception_colors()
347 346
348 347 self.set_colors(color_scheme)
349 348 self.old_scheme = color_scheme # save initial value for toggles
350 349
351 350 if call_pdb:
352 351 self.pdb = debugger.Pdb(self.color_scheme_table.active_scheme_name)
353 352 else:
354 353 self.pdb = None
355 354
356 355 def _get_ostream(self):
357 356 """Output stream that exceptions are written to.
358 357
359 358 Valid values are:
360 359
361 360 - None: the default, which means that IPython will dynamically resolve
362 361 to io.stdout. This ensures compatibility with most tools, including
363 362 Windows (where plain stdout doesn't recognize ANSI escapes).
364 363
365 364 - Any object with 'write' and 'flush' attributes.
366 365 """
367 366 return io.stdout if self._ostream is None else self._ostream
368 367
369 368 def _set_ostream(self, val):
370 369 assert val is None or (hasattr(val, 'write') and hasattr(val, 'flush'))
371 370 self._ostream = val
372 371
373 372 ostream = property(_get_ostream, _set_ostream)
374 373
375 374 def set_colors(self,*args,**kw):
376 375 """Shorthand access to the color table scheme selector method."""
377 376
378 377 # Set own color table
379 378 self.color_scheme_table.set_active_scheme(*args,**kw)
380 379 # for convenience, set Colors to the active scheme
381 380 self.Colors = self.color_scheme_table.active_colors
382 381 # Also set colors of debugger
383 382 if hasattr(self,'pdb') and self.pdb is not None:
384 383 self.pdb.set_colors(*args,**kw)
385 384
386 385 def color_toggle(self):
387 386 """Toggle between the currently active color scheme and NoColor."""
388 387
389 388 if self.color_scheme_table.active_scheme_name == 'NoColor':
390 389 self.color_scheme_table.set_active_scheme(self.old_scheme)
391 390 self.Colors = self.color_scheme_table.active_colors
392 391 else:
393 392 self.old_scheme = self.color_scheme_table.active_scheme_name
394 393 self.color_scheme_table.set_active_scheme('NoColor')
395 394 self.Colors = self.color_scheme_table.active_colors
396 395
397 396 def stb2text(self, stb):
398 397 """Convert a structured traceback (a list) to a string."""
399 398 return '\n'.join(stb)
400 399
401 400 def text(self, etype, value, tb, tb_offset=None, context=5):
402 401 """Return formatted traceback.
403 402
404 403 Subclasses may override this if they add extra arguments.
405 404 """
406 405 tb_list = self.structured_traceback(etype, value, tb,
407 406 tb_offset, context)
408 407 return self.stb2text(tb_list)
409 408
410 409 def structured_traceback(self, etype, evalue, tb, tb_offset=None,
411 410 context=5, mode=None):
412 411 """Return a list of traceback frames.
413 412
414 413 Must be implemented by each class.
415 414 """
416 415 raise NotImplementedError()
417 416
418 417
419 418 #---------------------------------------------------------------------------
420 419 class ListTB(TBTools):
421 420 """Print traceback information from a traceback list, with optional color.
422 421
423 422 Calling requires 3 arguments: (etype, evalue, elist)
424 423 as would be obtained by::
425 424
426 425 etype, evalue, tb = sys.exc_info()
427 426 if tb:
428 427 elist = traceback.extract_tb(tb)
429 428 else:
430 429 elist = None
431 430
432 431 It can thus be used by programs which need to process the traceback before
433 432 printing (such as console replacements based on the code module from the
434 433 standard library).
435 434
436 435 Because they are meant to be called without a full traceback (only a
437 436 list), instances of this class can't call the interactive pdb debugger."""
438 437
439 438 def __init__(self,color_scheme = 'NoColor', call_pdb=False, ostream=None):
440 439 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
441 440 ostream=ostream)
442 441
443 442 def __call__(self, etype, value, elist):
444 443 self.ostream.flush()
445 444 self.ostream.write(self.text(etype, value, elist))
446 445 self.ostream.write('\n')
447 446
448 447 def structured_traceback(self, etype, value, elist, tb_offset=None,
449 448 context=5):
450 449 """Return a color formatted string with the traceback info.
451 450
452 451 Parameters
453 452 ----------
454 453 etype : exception type
455 454 Type of the exception raised.
456 455
457 456 value : object
458 457 Data stored in the exception
459 458
460 459 elist : list
461 460 List of frames, see class docstring for details.
462 461
463 462 tb_offset : int, optional
464 463 Number of frames in the traceback to skip. If not given, the
465 464 instance value is used (set in constructor).
466 465
467 466 context : int, optional
468 467 Number of lines of context information to print.
469 468
470 469 Returns
471 470 -------
472 471 String with formatted exception.
473 472 """
474 473 tb_offset = self.tb_offset if tb_offset is None else tb_offset
475 474 Colors = self.Colors
476 475 out_list = []
477 476 if elist:
478 477
479 478 if tb_offset and len(elist) > tb_offset:
480 479 elist = elist[tb_offset:]
481 480
482 481 out_list.append('Traceback %s(most recent call last)%s:' %
483 482 (Colors.normalEm, Colors.Normal) + '\n')
484 483 out_list.extend(self._format_list(elist))
485 484 # The exception info should be a single entry in the list.
486 485 lines = ''.join(self._format_exception_only(etype, value))
487 486 out_list.append(lines)
488 487
489 488 # Note: this code originally read:
490 489
491 490 ## for line in lines[:-1]:
492 491 ## out_list.append(" "+line)
493 492 ## out_list.append(lines[-1])
494 493
495 494 # This means it was indenting everything but the last line by a little
496 495 # bit. I've disabled this for now, but if we see ugliness somewhre we
497 496 # can restore it.
498 497
499 498 return out_list
500 499
501 500 def _format_list(self, extracted_list):
502 501 """Format a list of traceback entry tuples for printing.
503 502
504 503 Given a list of tuples as returned by extract_tb() or
505 504 extract_stack(), return a list of strings ready for printing.
506 505 Each string in the resulting list corresponds to the item with the
507 506 same index in the argument list. Each string ends in a newline;
508 507 the strings may contain internal newlines as well, for those items
509 508 whose source text line is not None.
510 509
511 510 Lifted almost verbatim from traceback.py
512 511 """
513 512
514 513 Colors = self.Colors
515 514 list = []
516 515 for filename, lineno, name, line in extracted_list[:-1]:
517 516 item = ' File %s"%s"%s, line %s%d%s, in %s%s%s\n' % \
518 517 (Colors.filename, filename, Colors.Normal,
519 518 Colors.lineno, lineno, Colors.Normal,
520 519 Colors.name, name, Colors.Normal)
521 520 if line:
522 521 item += ' %s\n' % line.strip()
523 522 list.append(item)
524 523 # Emphasize the last entry
525 524 filename, lineno, name, line = extracted_list[-1]
526 525 item = '%s File %s"%s"%s, line %s%d%s, in %s%s%s%s\n' % \
527 526 (Colors.normalEm,
528 527 Colors.filenameEm, filename, Colors.normalEm,
529 528 Colors.linenoEm, lineno, Colors.normalEm,
530 529 Colors.nameEm, name, Colors.normalEm,
531 530 Colors.Normal)
532 531 if line:
533 532 item += '%s %s%s\n' % (Colors.line, line.strip(),
534 533 Colors.Normal)
535 534 list.append(item)
536 535 #from pprint import pformat; print 'LISTTB', pformat(list) # dbg
537 536 return list
538 537
539 538 def _format_exception_only(self, etype, value):
540 539 """Format the exception part of a traceback.
541 540
542 541 The arguments are the exception type and value such as given by
543 542 sys.exc_info()[:2]. The return value is a list of strings, each ending
544 543 in a newline. Normally, the list contains a single string; however,
545 544 for SyntaxError exceptions, it contains several lines that (when
546 545 printed) display detailed information about where the syntax error
547 546 occurred. The message indicating which exception occurred is the
548 547 always last string in the list.
549 548
550 549 Also lifted nearly verbatim from traceback.py
551 550 """
552 551 have_filedata = False
553 552 Colors = self.Colors
554 553 list = []
555 554 stype = Colors.excName + etype.__name__ + Colors.Normal
556 555 if value is None:
557 556 # Not sure if this can still happen in Python 2.6 and above
558 557 list.append( py3compat.cast_unicode(stype) + '\n')
559 558 else:
560 559 if issubclass(etype, SyntaxError):
561 560 have_filedata = True
562 561 #print 'filename is',filename # dbg
563 562 if not value.filename: value.filename = "<string>"
564 563 if value.lineno:
565 564 lineno = value.lineno
566 565 textline = ulinecache.getline(value.filename, value.lineno)
567 566 else:
568 567 lineno = 'unknown'
569 568 textline = ''
570 569 list.append('%s File %s"%s"%s, line %s%s%s\n' % \
571 570 (Colors.normalEm,
572 571 Colors.filenameEm, py3compat.cast_unicode(value.filename), Colors.normalEm,
573 572 Colors.linenoEm, lineno, Colors.Normal ))
574 573 if textline == '':
575 574 textline = py3compat.cast_unicode(value.text, "utf-8")
576 575
577 576 if textline is not None:
578 577 i = 0
579 578 while i < len(textline) and textline[i].isspace():
580 579 i += 1
581 580 list.append('%s %s%s\n' % (Colors.line,
582 581 textline.strip(),
583 582 Colors.Normal))
584 583 if value.offset is not None:
585 584 s = ' '
586 585 for c in textline[i:value.offset-1]:
587 586 if c.isspace():
588 587 s += c
589 588 else:
590 589 s += ' '
591 590 list.append('%s%s^%s\n' % (Colors.caret, s,
592 591 Colors.Normal) )
593 592
594 593 try:
595 594 s = value.msg
596 595 except Exception:
597 596 s = self._some_str(value)
598 597 if s:
599 598 list.append('%s%s:%s %s\n' % (str(stype), Colors.excName,
600 599 Colors.Normal, s))
601 600 else:
602 601 list.append('%s\n' % str(stype))
603 602
604 603 # sync with user hooks
605 604 if have_filedata:
606 605 ipinst = ipapi.get()
607 606 if ipinst is not None:
608 607 ipinst.hooks.synchronize_with_editor(value.filename, value.lineno, 0)
609 608
610 609 return list
611 610
612 611 def get_exception_only(self, etype, value):
613 612 """Only print the exception type and message, without a traceback.
614 613
615 614 Parameters
616 615 ----------
617 616 etype : exception type
618 617 value : exception value
619 618 """
620 619 return ListTB.structured_traceback(self, etype, value, [])
621 620
622 621
623 622 def show_exception_only(self, etype, evalue):
624 623 """Only print the exception type and message, without a traceback.
625 624
626 625 Parameters
627 626 ----------
628 627 etype : exception type
629 628 value : exception value
630 629 """
631 630 # This method needs to use __call__ from *this* class, not the one from
632 631 # a subclass whose signature or behavior may be different
633 632 ostream = self.ostream
634 633 ostream.flush()
635 634 ostream.write('\n'.join(self.get_exception_only(etype, evalue)))
636 635 ostream.flush()
637 636
638 637 def _some_str(self, value):
639 638 # Lifted from traceback.py
640 639 try:
641 640 return str(value)
642 641 except:
643 642 return '<unprintable %s object>' % type(value).__name__
644 643
645 644 #----------------------------------------------------------------------------
646 645 class VerboseTB(TBTools):
647 646 """A port of Ka-Ping Yee's cgitb.py module that outputs color text instead
648 647 of HTML. Requires inspect and pydoc. Crazy, man.
649 648
650 649 Modified version which optionally strips the topmost entries from the
651 650 traceback, to be used with alternate interpreters (because their own code
652 651 would appear in the traceback)."""
653 652
654 653 def __init__(self,color_scheme = 'Linux', call_pdb=False, ostream=None,
655 654 tb_offset=0, long_header=False, include_vars=True,
656 655 check_cache=None):
657 656 """Specify traceback offset, headers and color scheme.
658 657
659 658 Define how many frames to drop from the tracebacks. Calling it with
660 659 tb_offset=1 allows use of this handler in interpreters which will have
661 660 their own code at the top of the traceback (VerboseTB will first
662 661 remove that frame before printing the traceback info)."""
663 662 TBTools.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
664 663 ostream=ostream)
665 664 self.tb_offset = tb_offset
666 665 self.long_header = long_header
667 666 self.include_vars = include_vars
668 667 # By default we use linecache.checkcache, but the user can provide a
669 668 # different check_cache implementation. This is used by the IPython
670 669 # kernel to provide tracebacks for interactive code that is cached,
671 670 # by a compiler instance that flushes the linecache but preserves its
672 671 # own code cache.
673 672 if check_cache is None:
674 673 check_cache = linecache.checkcache
675 674 self.check_cache = check_cache
676 675
677 676 def structured_traceback(self, etype, evalue, etb, tb_offset=None,
678 677 context=5):
679 678 """Return a nice text document describing the traceback."""
680 679
681 680 tb_offset = self.tb_offset if tb_offset is None else tb_offset
682 681
683 682 # some locals
684 683 try:
685 684 etype = etype.__name__
686 685 except AttributeError:
687 686 pass
688 687 Colors = self.Colors # just a shorthand + quicker name lookup
689 688 ColorsNormal = Colors.Normal # used a lot
690 689 col_scheme = self.color_scheme_table.active_scheme_name
691 690 indent = ' '*INDENT_SIZE
692 691 em_normal = '%s\n%s%s' % (Colors.valEm, indent,ColorsNormal)
693 692 undefined = '%sundefined%s' % (Colors.em, ColorsNormal)
694 693 exc = '%s%s%s' % (Colors.excName,etype,ColorsNormal)
695 694
696 695 # some internal-use functions
697 696 def text_repr(value):
698 697 """Hopefully pretty robust repr equivalent."""
699 698 # this is pretty horrible but should always return *something*
700 699 try:
701 700 return pydoc.text.repr(value)
702 701 except KeyboardInterrupt:
703 702 raise
704 703 except:
705 704 try:
706 705 return repr(value)
707 706 except KeyboardInterrupt:
708 707 raise
709 708 except:
710 709 try:
711 710 # all still in an except block so we catch
712 711 # getattr raising
713 712 name = getattr(value, '__name__', None)
714 713 if name:
715 714 # ick, recursion
716 715 return text_repr(name)
717 716 klass = getattr(value, '__class__', None)
718 717 if klass:
719 718 return '%s instance' % text_repr(klass)
720 719 except KeyboardInterrupt:
721 720 raise
722 721 except:
723 722 return 'UNRECOVERABLE REPR FAILURE'
724 723 def eqrepr(value, repr=text_repr): return '=%s' % repr(value)
725 724 def nullrepr(value, repr=text_repr): return ''
726 725
727 726 # meat of the code begins
728 727 try:
729 728 etype = etype.__name__
730 729 except AttributeError:
731 730 pass
732 731
733 732 if self.long_header:
734 733 # Header with the exception type, python version, and date
735 734 pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable
736 735 date = time.ctime(time.time())
737 736
738 737 head = '%s%s%s\n%s%s%s\n%s' % (Colors.topline, '-'*75, ColorsNormal,
739 738 exc, ' '*(75-len(str(etype))-len(pyver)),
740 739 pyver, date.rjust(75) )
741 740 head += "\nA problem occured executing Python code. Here is the sequence of function"\
742 741 "\ncalls leading up to the error, with the most recent (innermost) call last."
743 742 else:
744 743 # Simplified header
745 744 head = '%s%s%s\n%s%s' % (Colors.topline, '-'*75, ColorsNormal,exc,
746 745 'Traceback (most recent call last)'.\
747 746 rjust(75 - len(str(etype)) ) )
748 747 frames = []
749 748 # Flush cache before calling inspect. This helps alleviate some of the
750 749 # problems with python 2.3's inspect.py.
751 750 ##self.check_cache()
752 751 # Drop topmost frames if requested
753 752 try:
754 753 # Try the default getinnerframes and Alex's: Alex's fixes some
755 754 # problems, but it generates empty tracebacks for console errors
756 755 # (5 blanks lines) where none should be returned.
757 756 #records = inspect.getinnerframes(etb, context)[tb_offset:]
758 757 #print 'python records:', records # dbg
759 758 records = _fixed_getinnerframes(etb, context, tb_offset)
760 759 #print 'alex records:', records # dbg
761 760 except:
762 761
763 762 # FIXME: I've been getting many crash reports from python 2.3
764 763 # users, traceable to inspect.py. If I can find a small test-case
765 764 # to reproduce this, I should either write a better workaround or
766 765 # file a bug report against inspect (if that's the real problem).
767 766 # So far, I haven't been able to find an isolated example to
768 767 # reproduce the problem.
769 768 inspect_error()
770 769 traceback.print_exc(file=self.ostream)
771 770 info('\nUnfortunately, your original traceback can not be constructed.\n')
772 771 return ''
773 772
774 773 # build some color string templates outside these nested loops
775 774 tpl_link = '%s%%s%s' % (Colors.filenameEm,ColorsNormal)
776 775 tpl_call = 'in %s%%s%s%%s%s' % (Colors.vName, Colors.valEm,
777 776 ColorsNormal)
778 777 tpl_call_fail = 'in %s%%s%s(***failed resolving arguments***)%s' % \
779 778 (Colors.vName, Colors.valEm, ColorsNormal)
780 779 tpl_local_var = '%s%%s%s' % (Colors.vName, ColorsNormal)
781 780 tpl_global_var = '%sglobal%s %s%%s%s' % (Colors.em, ColorsNormal,
782 781 Colors.vName, ColorsNormal)
783 782 tpl_name_val = '%%s %s= %%s%s' % (Colors.valEm, ColorsNormal)
784 783 tpl_line = '%s%%s%s %%s' % (Colors.lineno, ColorsNormal)
785 784 tpl_line_em = '%s%%s%s %%s%s' % (Colors.linenoEm,Colors.line,
786 785 ColorsNormal)
787 786
788 787 # now, loop over all records printing context and info
789 788 abspath = os.path.abspath
790 789 for frame, file, lnum, func, lines, index in records:
791 790 #print '*** record:',file,lnum,func,lines,index # dbg
792 791 if not file:
793 792 file = '?'
794 793 elif not(file.startswith(str("<")) and file.endswith(str(">"))):
795 794 # Guess that filenames like <string> aren't real filenames, so
796 795 # don't call abspath on them.
797 796 try:
798 797 file = abspath(file)
799 798 except OSError:
800 799 # Not sure if this can still happen: abspath now works with
801 800 # file names like <string>
802 801 pass
803 802 file = py3compat.cast_unicode(file, util_path.fs_encoding)
804 803 link = tpl_link % file
805 804 args, varargs, varkw, locals = inspect.getargvalues(frame)
806 805
807 806 if func == '?':
808 807 call = ''
809 808 else:
810 809 # Decide whether to include variable details or not
811 810 var_repr = self.include_vars and eqrepr or nullrepr
812 811 try:
813 812 call = tpl_call % (func,inspect.formatargvalues(args,
814 813 varargs, varkw,
815 814 locals,formatvalue=var_repr))
816 815 except KeyError:
817 816 # This happens in situations like errors inside generator
818 817 # expressions, where local variables are listed in the
819 818 # line, but can't be extracted from the frame. I'm not
820 819 # 100% sure this isn't actually a bug in inspect itself,
821 820 # but since there's no info for us to compute with, the
822 821 # best we can do is report the failure and move on. Here
823 822 # we must *not* call any traceback construction again,
824 823 # because that would mess up use of %debug later on. So we
825 824 # simply report the failure and move on. The only
826 825 # limitation will be that this frame won't have locals
827 826 # listed in the call signature. Quite subtle problem...
828 827 # I can't think of a good way to validate this in a unit
829 828 # test, but running a script consisting of:
830 829 # dict( (k,v.strip()) for (k,v) in range(10) )
831 830 # will illustrate the error, if this exception catch is
832 831 # disabled.
833 832 call = tpl_call_fail % func
834 833
835 834 # Don't attempt to tokenize binary files.
836 835 if file.endswith(('.so', '.pyd', '.dll')):
837 836 frames.append('%s %s\n' % (link,call))
838 837 continue
839 838 elif file.endswith(('.pyc','.pyo')):
840 839 # Look up the corresponding source file.
841 840 file = pyfile.source_from_cache(file)
842 841
843 842 def linereader(file=file, lnum=[lnum], getline=ulinecache.getline):
844 843 line = getline(file, lnum[0])
845 844 lnum[0] += 1
846 845 return line
847 846
848 847 # Build the list of names on this line of code where the exception
849 848 # occurred.
850 849 try:
851 850 names = []
852 851 name_cont = False
853 852
854 853 for token_type, token, start, end, line in generate_tokens(linereader):
855 854 # build composite names
856 855 if token_type == tokenize.NAME and token not in keyword.kwlist:
857 856 if name_cont:
858 857 # Continuation of a dotted name
859 858 try:
860 859 names[-1].append(token)
861 860 except IndexError:
862 861 names.append([token])
863 862 name_cont = False
864 863 else:
865 864 # Regular new names. We append everything, the caller
866 865 # will be responsible for pruning the list later. It's
867 866 # very tricky to try to prune as we go, b/c composite
868 867 # names can fool us. The pruning at the end is easy
869 868 # to do (or the caller can print a list with repeated
870 869 # names if so desired.
871 870 names.append([token])
872 871 elif token == '.':
873 872 name_cont = True
874 873 elif token_type == tokenize.NEWLINE:
875 874 break
876 875
877 876 except (IndexError, UnicodeDecodeError):
878 877 # signals exit of tokenizer
879 878 pass
880 879 except tokenize.TokenError as msg:
881 880 _m = ("An unexpected error occurred while tokenizing input\n"
882 881 "The following traceback may be corrupted or invalid\n"
883 882 "The error message is: %s\n" % msg)
884 883 error(_m)
885 884
886 885 # Join composite names (e.g. "dict.fromkeys")
887 886 names = ['.'.join(n) for n in names]
888 887 # prune names list of duplicates, but keep the right order
889 888 unique_names = uniq_stable(names)
890 889
891 890 # Start loop over vars
892 891 lvals = []
893 892 if self.include_vars:
894 893 for name_full in unique_names:
895 894 name_base = name_full.split('.',1)[0]
896 895 if name_base in frame.f_code.co_varnames:
897 896 if name_base in locals:
898 897 try:
899 898 value = repr(eval(name_full,locals))
900 899 except:
901 900 value = undefined
902 901 else:
903 902 value = undefined
904 903 name = tpl_local_var % name_full
905 904 else:
906 905 if name_base in frame.f_globals:
907 906 try:
908 907 value = repr(eval(name_full,frame.f_globals))
909 908 except:
910 909 value = undefined
911 910 else:
912 911 value = undefined
913 912 name = tpl_global_var % name_full
914 913 lvals.append(tpl_name_val % (name,value))
915 914 if lvals:
916 915 lvals = '%s%s' % (indent,em_normal.join(lvals))
917 916 else:
918 917 lvals = ''
919 918
920 919 level = '%s %s\n' % (link,call)
921 920
922 921 if index is None:
923 922 frames.append(level)
924 923 else:
925 924 frames.append('%s%s' % (level,''.join(
926 925 _format_traceback_lines(lnum,index,lines,Colors,lvals,
927 926 col_scheme))))
928 927
929 928 # Get (safely) a string form of the exception info
930 929 try:
931 930 etype_str,evalue_str = map(str,(etype,evalue))
932 931 except:
933 932 # User exception is improperly defined.
934 933 etype,evalue = str,sys.exc_info()[:2]
935 934 etype_str,evalue_str = map(str,(etype,evalue))
936 935 # ... and format it
937 936 exception = ['%s%s%s: %s' % (Colors.excName, etype_str,
938 937 ColorsNormal, py3compat.cast_unicode(evalue_str))]
939 938 if (not py3compat.PY3) and type(evalue) is types.InstanceType:
940 939 try:
941 940 names = [w for w in dir(evalue) if isinstance(w, basestring)]
942 941 except:
943 942 # Every now and then, an object with funny inernals blows up
944 943 # when dir() is called on it. We do the best we can to report
945 944 # the problem and continue
946 945 _m = '%sException reporting error (object with broken dir())%s:'
947 946 exception.append(_m % (Colors.excName,ColorsNormal))
948 947 etype_str,evalue_str = map(str,sys.exc_info()[:2])
949 948 exception.append('%s%s%s: %s' % (Colors.excName,etype_str,
950 949 ColorsNormal, py3compat.cast_unicode(evalue_str)))
951 950 names = []
952 951 for name in names:
953 952 value = text_repr(getattr(evalue, name))
954 953 exception.append('\n%s%s = %s' % (indent, name, value))
955 954
956 955 # vds: >>
957 956 if records:
958 957 filepath, lnum = records[-1][1:3]
959 958 #print "file:", str(file), "linenb", str(lnum) # dbg
960 959 filepath = os.path.abspath(filepath)
961 960 ipinst = ipapi.get()
962 961 if ipinst is not None:
963 962 ipinst.hooks.synchronize_with_editor(filepath, lnum, 0)
964 963 # vds: <<
965 964
966 965 # return all our info assembled as a single string
967 966 # return '%s\n\n%s\n%s' % (head,'\n'.join(frames),''.join(exception[0]) )
968 967 return [head] + frames + [''.join(exception[0])]
969 968
970 969 def debugger(self,force=False):
971 970 """Call up the pdb debugger if desired, always clean up the tb
972 971 reference.
973 972
974 973 Keywords:
975 974
976 975 - force(False): by default, this routine checks the instance call_pdb
977 976 flag and does not actually invoke the debugger if the flag is false.
978 977 The 'force' option forces the debugger to activate even if the flag
979 978 is false.
980 979
981 980 If the call_pdb flag is set, the pdb interactive debugger is
982 981 invoked. In all cases, the self.tb reference to the current traceback
983 982 is deleted to prevent lingering references which hamper memory
984 983 management.
985 984
986 985 Note that each call to pdb() does an 'import readline', so if your app
987 986 requires a special setup for the readline completers, you'll have to
988 987 fix that by hand after invoking the exception handler."""
989 988
990 989 if force or self.call_pdb:
991 990 if self.pdb is None:
992 991 self.pdb = debugger.Pdb(
993 992 self.color_scheme_table.active_scheme_name)
994 993 # the system displayhook may have changed, restore the original
995 994 # for pdb
996 995 display_trap = DisplayTrap(hook=sys.__displayhook__)
997 996 with display_trap:
998 997 self.pdb.reset()
999 998 # Find the right frame so we don't pop up inside ipython itself
1000 999 if hasattr(self,'tb') and self.tb is not None:
1001 1000 etb = self.tb
1002 1001 else:
1003 1002 etb = self.tb = sys.last_traceback
1004 1003 while self.tb is not None and self.tb.tb_next is not None:
1005 1004 self.tb = self.tb.tb_next
1006 1005 if etb and etb.tb_next:
1007 1006 etb = etb.tb_next
1008 1007 self.pdb.botframe = etb.tb_frame
1009 1008 self.pdb.interaction(self.tb.tb_frame, self.tb)
1010 1009
1011 1010 if hasattr(self,'tb'):
1012 1011 del self.tb
1013 1012
1014 1013 def handler(self, info=None):
1015 1014 (etype, evalue, etb) = info or sys.exc_info()
1016 1015 self.tb = etb
1017 1016 ostream = self.ostream
1018 1017 ostream.flush()
1019 1018 ostream.write(self.text(etype, evalue, etb))
1020 1019 ostream.write('\n')
1021 1020 ostream.flush()
1022 1021
1023 1022 # Changed so an instance can just be called as VerboseTB_inst() and print
1024 1023 # out the right info on its own.
1025 1024 def __call__(self, etype=None, evalue=None, etb=None):
1026 1025 """This hook can replace sys.excepthook (for Python 2.1 or higher)."""
1027 1026 if etb is None:
1028 1027 self.handler()
1029 1028 else:
1030 1029 self.handler((etype, evalue, etb))
1031 1030 try:
1032 1031 self.debugger()
1033 1032 except KeyboardInterrupt:
1034 1033 print "\nKeyboardInterrupt"
1035 1034
1036 1035 #----------------------------------------------------------------------------
1037 1036 class FormattedTB(VerboseTB, ListTB):
1038 1037 """Subclass ListTB but allow calling with a traceback.
1039 1038
1040 1039 It can thus be used as a sys.excepthook for Python > 2.1.
1041 1040
1042 1041 Also adds 'Context' and 'Verbose' modes, not available in ListTB.
1043 1042
1044 1043 Allows a tb_offset to be specified. This is useful for situations where
1045 1044 one needs to remove a number of topmost frames from the traceback (such as
1046 1045 occurs with python programs that themselves execute other python code,
1047 1046 like Python shells). """
1048 1047
1049 1048 def __init__(self, mode='Plain', color_scheme='Linux', call_pdb=False,
1050 1049 ostream=None,
1051 1050 tb_offset=0, long_header=False, include_vars=False,
1052 1051 check_cache=None):
1053 1052
1054 1053 # NEVER change the order of this list. Put new modes at the end:
1055 1054 self.valid_modes = ['Plain','Context','Verbose']
1056 1055 self.verbose_modes = self.valid_modes[1:3]
1057 1056
1058 1057 VerboseTB.__init__(self, color_scheme=color_scheme, call_pdb=call_pdb,
1059 1058 ostream=ostream, tb_offset=tb_offset,
1060 1059 long_header=long_header, include_vars=include_vars,
1061 1060 check_cache=check_cache)
1062 1061
1063 1062 # Different types of tracebacks are joined with different separators to
1064 1063 # form a single string. They are taken from this dict
1065 1064 self._join_chars = dict(Plain='', Context='\n', Verbose='\n')
1066 1065 # set_mode also sets the tb_join_char attribute
1067 1066 self.set_mode(mode)
1068 1067
1069 1068 def _extract_tb(self,tb):
1070 1069 if tb:
1071 1070 return traceback.extract_tb(tb)
1072 1071 else:
1073 1072 return None
1074 1073
1075 1074 def structured_traceback(self, etype, value, tb, tb_offset=None, context=5):
1076 1075 tb_offset = self.tb_offset if tb_offset is None else tb_offset
1077 1076 mode = self.mode
1078 1077 if mode in self.verbose_modes:
1079 1078 # Verbose modes need a full traceback
1080 1079 return VerboseTB.structured_traceback(
1081 1080 self, etype, value, tb, tb_offset, context
1082 1081 )
1083 1082 else:
1084 1083 # We must check the source cache because otherwise we can print
1085 1084 # out-of-date source code.
1086 1085 self.check_cache()
1087 1086 # Now we can extract and format the exception
1088 1087 elist = self._extract_tb(tb)
1089 1088 return ListTB.structured_traceback(
1090 1089 self, etype, value, elist, tb_offset, context
1091 1090 )
1092 1091
1093 1092 def stb2text(self, stb):
1094 1093 """Convert a structured traceback (a list) to a string."""
1095 1094 return self.tb_join_char.join(stb)
1096 1095
1097 1096
1098 1097 def set_mode(self,mode=None):
1099 1098 """Switch to the desired mode.
1100 1099
1101 1100 If mode is not specified, cycles through the available modes."""
1102 1101
1103 1102 if not mode:
1104 1103 new_idx = ( self.valid_modes.index(self.mode) + 1 ) % \
1105 1104 len(self.valid_modes)
1106 1105 self.mode = self.valid_modes[new_idx]
1107 1106 elif mode not in self.valid_modes:
1108 1107 raise ValueError('Unrecognized mode in FormattedTB: <'+mode+'>\n'
1109 1108 'Valid modes: '+str(self.valid_modes))
1110 1109 else:
1111 1110 self.mode = mode
1112 1111 # include variable details only in 'Verbose' mode
1113 1112 self.include_vars = (self.mode == self.valid_modes[2])
1114 1113 # Set the join character for generating text tracebacks
1115 1114 self.tb_join_char = self._join_chars[self.mode]
1116 1115
1117 1116 # some convenient shorcuts
1118 1117 def plain(self):
1119 1118 self.set_mode(self.valid_modes[0])
1120 1119
1121 1120 def context(self):
1122 1121 self.set_mode(self.valid_modes[1])
1123 1122
1124 1123 def verbose(self):
1125 1124 self.set_mode(self.valid_modes[2])
1126 1125
1127 1126 #----------------------------------------------------------------------------
1128 1127 class AutoFormattedTB(FormattedTB):
1129 1128 """A traceback printer which can be called on the fly.
1130 1129
1131 1130 It will find out about exceptions by itself.
1132 1131
1133 1132 A brief example::
1134 1133
1135 1134 AutoTB = AutoFormattedTB(mode = 'Verbose',color_scheme='Linux')
1136 1135 try:
1137 1136 ...
1138 1137 except:
1139 1138 AutoTB() # or AutoTB(out=logfile) where logfile is an open file object
1140 1139 """
1141 1140
1142 1141 def __call__(self,etype=None,evalue=None,etb=None,
1143 1142 out=None,tb_offset=None):
1144 1143 """Print out a formatted exception traceback.
1145 1144
1146 1145 Optional arguments:
1147 1146 - out: an open file-like object to direct output to.
1148 1147
1149 1148 - tb_offset: the number of frames to skip over in the stack, on a
1150 1149 per-call basis (this overrides temporarily the instance's tb_offset
1151 1150 given at initialization time. """
1152 1151
1153 1152
1154 1153 if out is None:
1155 1154 out = self.ostream
1156 1155 out.flush()
1157 1156 out.write(self.text(etype, evalue, etb, tb_offset))
1158 1157 out.write('\n')
1159 1158 out.flush()
1160 1159 # FIXME: we should remove the auto pdb behavior from here and leave
1161 1160 # that to the clients.
1162 1161 try:
1163 1162 self.debugger()
1164 1163 except KeyboardInterrupt:
1165 1164 print "\nKeyboardInterrupt"
1166 1165
1167 1166 def structured_traceback(self, etype=None, value=None, tb=None,
1168 1167 tb_offset=None, context=5):
1169 1168 if etype is None:
1170 1169 etype,value,tb = sys.exc_info()
1171 1170 self.tb = tb
1172 1171 return FormattedTB.structured_traceback(
1173 1172 self, etype, value, tb, tb_offset, context)
1174 1173
1175 1174 #---------------------------------------------------------------------------
1176 1175
1177 1176 # A simple class to preserve Nathan's original functionality.
1178 1177 class ColorTB(FormattedTB):
1179 1178 """Shorthand to initialize a FormattedTB in Linux colors mode."""
1180 1179 def __init__(self,color_scheme='Linux',call_pdb=0):
1181 1180 FormattedTB.__init__(self,color_scheme=color_scheme,
1182 1181 call_pdb=call_pdb)
1183 1182
1184 1183
1185 1184 class SyntaxTB(ListTB):
1186 1185 """Extension which holds some state: the last exception value"""
1187 1186
1188 1187 def __init__(self,color_scheme = 'NoColor'):
1189 1188 ListTB.__init__(self,color_scheme)
1190 1189 self.last_syntax_error = None
1191 1190
1192 1191 def __call__(self, etype, value, elist):
1193 1192 self.last_syntax_error = value
1194 1193 ListTB.__call__(self,etype,value,elist)
1195 1194
1196 1195 def clear_err_state(self):
1197 1196 """Return the current error state and clear it"""
1198 1197 e = self.last_syntax_error
1199 1198 self.last_syntax_error = None
1200 1199 return e
1201 1200
1202 1201 def stb2text(self, stb):
1203 1202 """Convert a structured traceback (a list) to a string."""
1204 1203 return ''.join(stb)
1205 1204
1206 1205
1207 1206 #----------------------------------------------------------------------------
1208 1207 # module testing (minimal)
1209 1208 if __name__ == "__main__":
1210 1209 def spam(c, d_e):
1211 1210 (d, e) = d_e
1212 1211 x = c + d
1213 1212 y = c * d
1214 1213 foo(x, y)
1215 1214
1216 1215 def foo(a, b, bar=1):
1217 1216 eggs(a, b + bar)
1218 1217
1219 1218 def eggs(f, g, z=globals()):
1220 1219 h = f + g
1221 1220 i = f - g
1222 1221 return h / i
1223 1222
1224 1223 print ''
1225 1224 print '*** Before ***'
1226 1225 try:
1227 1226 print spam(1, (2, 3))
1228 1227 except:
1229 1228 traceback.print_exc()
1230 1229 print ''
1231 1230
1232 1231 handler = ColorTB()
1233 1232 print '*** ColorTB ***'
1234 1233 try:
1235 1234 print spam(1, (2, 3))
1236 1235 except:
1237 1236 handler(*sys.exc_info())
1238 1237 print ''
1239 1238
1240 1239 handler = VerboseTB()
1241 1240 print '*** VerboseTB ***'
1242 1241 try:
1243 1242 print spam(1, (2, 3))
1244 1243 except:
1245 1244 handler(*sys.exc_info())
1246 1245 print ''
1247 1246
@@ -1,483 +1,483 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Manage background (threaded) jobs conveniently from an interactive shell.
3 3
4 4 This module provides a BackgroundJobManager class. This is the main class
5 5 meant for public usage, it implements an object which can create and manage
6 6 new background jobs.
7 7
8 8 It also provides the actual job classes managed by these BackgroundJobManager
9 9 objects, see their docstrings below.
10 10
11 11
12 12 This system was inspired by discussions with B. Granger and the
13 13 BackgroundCommand class described in the book Python Scripting for
14 14 Computational Science, by H. P. Langtangen:
15 15
16 16 http://folk.uio.no/hpl/scripting
17 17
18 18 (although ultimately no code from this text was used, as IPython's system is a
19 19 separate implementation).
20 20
21 21 An example notebook is provided in our documentation illustrating interactive
22 22 use of the system.
23 23 """
24 24
25 25 #*****************************************************************************
26 26 # Copyright (C) 2005-2006 Fernando Perez <fperez@colorado.edu>
27 27 #
28 28 # Distributed under the terms of the BSD License. The full license is in
29 29 # the file COPYING, distributed as part of this software.
30 30 #*****************************************************************************
31 31
32 32 # Code begins
33 33 import sys
34 34 import threading
35 35
36 36 from IPython.core.ultratb import AutoFormattedTB
37 from IPython.utils.warn import warn, error
37 from IPython.utils.warn import error
38 38
39 39
40 40 class BackgroundJobManager(object):
41 41 """Class to manage a pool of backgrounded threaded jobs.
42 42
43 43 Below, we assume that 'jobs' is a BackgroundJobManager instance.
44 44
45 45 Usage summary (see the method docstrings for details):
46 46
47 47 jobs.new(...) -> start a new job
48 48
49 49 jobs() or jobs.status() -> print status summary of all jobs
50 50
51 51 jobs[N] -> returns job number N.
52 52
53 53 foo = jobs[N].result -> assign to variable foo the result of job N
54 54
55 55 jobs[N].traceback() -> print the traceback of dead job N
56 56
57 57 jobs.remove(N) -> remove (finished) job N
58 58
59 59 jobs.flush() -> remove all finished jobs
60 60
61 61 As a convenience feature, BackgroundJobManager instances provide the
62 62 utility result and traceback methods which retrieve the corresponding
63 63 information from the jobs list:
64 64
65 65 jobs.result(N) <--> jobs[N].result
66 66 jobs.traceback(N) <--> jobs[N].traceback()
67 67
68 68 While this appears minor, it allows you to use tab completion
69 69 interactively on the job manager instance.
70 70 """
71 71
72 72 def __init__(self):
73 73 # Lists for job management, accessed via a property to ensure they're
74 74 # up to date.x
75 75 self._running = []
76 76 self._completed = []
77 77 self._dead = []
78 78 # A dict of all jobs, so users can easily access any of them
79 79 self.all = {}
80 80 # For reporting
81 81 self._comp_report = []
82 82 self._dead_report = []
83 83 # Store status codes locally for fast lookups
84 84 self._s_created = BackgroundJobBase.stat_created_c
85 85 self._s_running = BackgroundJobBase.stat_running_c
86 86 self._s_completed = BackgroundJobBase.stat_completed_c
87 87 self._s_dead = BackgroundJobBase.stat_dead_c
88 88
89 89 @property
90 90 def running(self):
91 91 self._update_status()
92 92 return self._running
93 93
94 94 @property
95 95 def dead(self):
96 96 self._update_status()
97 97 return self._dead
98 98
99 99 @property
100 100 def completed(self):
101 101 self._update_status()
102 102 return self._completed
103 103
104 104 def new(self, func_or_exp, *args, **kwargs):
105 105 """Add a new background job and start it in a separate thread.
106 106
107 107 There are two types of jobs which can be created:
108 108
109 109 1. Jobs based on expressions which can be passed to an eval() call.
110 110 The expression must be given as a string. For example:
111 111
112 112 job_manager.new('myfunc(x,y,z=1)'[,glob[,loc]])
113 113
114 114 The given expression is passed to eval(), along with the optional
115 115 global/local dicts provided. If no dicts are given, they are
116 116 extracted automatically from the caller's frame.
117 117
118 118 A Python statement is NOT a valid eval() expression. Basically, you
119 119 can only use as an eval() argument something which can go on the right
120 120 of an '=' sign and be assigned to a variable.
121 121
122 122 For example,"print 'hello'" is not valid, but '2+3' is.
123 123
124 124 2. Jobs given a function object, optionally passing additional
125 125 positional arguments:
126 126
127 127 job_manager.new(myfunc, x, y)
128 128
129 129 The function is called with the given arguments.
130 130
131 131 If you need to pass keyword arguments to your function, you must
132 132 supply them as a dict named kw:
133 133
134 134 job_manager.new(myfunc, x, y, kw=dict(z=1))
135 135
136 136 The reason for this assymmetry is that the new() method needs to
137 137 maintain access to its own keywords, and this prevents name collisions
138 138 between arguments to new() and arguments to your own functions.
139 139
140 140 In both cases, the result is stored in the job.result field of the
141 141 background job object.
142 142
143 143 You can set `daemon` attribute of the thread by giving the keyword
144 144 argument `daemon`.
145 145
146 146 Notes and caveats:
147 147
148 148 1. All threads running share the same standard output. Thus, if your
149 149 background jobs generate output, it will come out on top of whatever
150 150 you are currently writing. For this reason, background jobs are best
151 151 used with silent functions which simply return their output.
152 152
153 153 2. Threads also all work within the same global namespace, and this
154 154 system does not lock interactive variables. So if you send job to the
155 155 background which operates on a mutable object for a long time, and
156 156 start modifying that same mutable object interactively (or in another
157 157 backgrounded job), all sorts of bizarre behaviour will occur.
158 158
159 159 3. If a background job is spending a lot of time inside a C extension
160 160 module which does not release the Python Global Interpreter Lock
161 161 (GIL), this will block the IPython prompt. This is simply because the
162 162 Python interpreter can only switch between threads at Python
163 163 bytecodes. While the execution is inside C code, the interpreter must
164 164 simply wait unless the extension module releases the GIL.
165 165
166 166 4. There is no way, due to limitations in the Python threads library,
167 167 to kill a thread once it has started."""
168 168
169 169 if callable(func_or_exp):
170 170 kw = kwargs.get('kw',{})
171 171 job = BackgroundJobFunc(func_or_exp,*args,**kw)
172 172 elif isinstance(func_or_exp, basestring):
173 173 if not args:
174 174 frame = sys._getframe(1)
175 175 glob, loc = frame.f_globals, frame.f_locals
176 176 elif len(args)==1:
177 177 glob = loc = args[0]
178 178 elif len(args)==2:
179 179 glob,loc = args
180 180 else:
181 181 raise ValueError(
182 182 'Expression jobs take at most 2 args (globals,locals)')
183 183 job = BackgroundJobExpr(func_or_exp, glob, loc)
184 184 else:
185 185 raise TypeError('invalid args for new job')
186 186
187 187 if kwargs.get('daemon', False):
188 188 job.daemon = True
189 189 job.num = len(self.all)+1 if self.all else 0
190 190 self.running.append(job)
191 191 self.all[job.num] = job
192 192 print 'Starting job # %s in a separate thread.' % job.num
193 193 job.start()
194 194 return job
195 195
196 196 def __getitem__(self, job_key):
197 197 num = job_key if isinstance(job_key, int) else job_key.num
198 198 return self.all[num]
199 199
200 200 def __call__(self):
201 201 """An alias to self.status(),
202 202
203 203 This allows you to simply call a job manager instance much like the
204 204 Unix `jobs` shell command."""
205 205
206 206 return self.status()
207 207
208 208 def _update_status(self):
209 209 """Update the status of the job lists.
210 210
211 211 This method moves finished jobs to one of two lists:
212 212 - self.completed: jobs which completed successfully
213 213 - self.dead: jobs which finished but died.
214 214
215 215 It also copies those jobs to corresponding _report lists. These lists
216 216 are used to report jobs completed/dead since the last update, and are
217 217 then cleared by the reporting function after each call."""
218 218
219 219 # Status codes
220 220 srun, scomp, sdead = self._s_running, self._s_completed, self._s_dead
221 221 # State lists, use the actual lists b/c the public names are properties
222 222 # that call this very function on access
223 223 running, completed, dead = self._running, self._completed, self._dead
224 224
225 225 # Now, update all state lists
226 226 for num, job in enumerate(running):
227 227 stat = job.stat_code
228 228 if stat == srun:
229 229 continue
230 230 elif stat == scomp:
231 231 completed.append(job)
232 232 self._comp_report.append(job)
233 233 running[num] = False
234 234 elif stat == sdead:
235 235 dead.append(job)
236 236 self._dead_report.append(job)
237 237 running[num] = False
238 238 # Remove dead/completed jobs from running list
239 239 running[:] = filter(None, running)
240 240
241 241 def _group_report(self,group,name):
242 242 """Report summary for a given job group.
243 243
244 244 Return True if the group had any elements."""
245 245
246 246 if group:
247 247 print '%s jobs:' % name
248 248 for job in group:
249 249 print '%s : %s' % (job.num,job)
250 250 print
251 251 return True
252 252
253 253 def _group_flush(self,group,name):
254 254 """Flush a given job group
255 255
256 256 Return True if the group had any elements."""
257 257
258 258 njobs = len(group)
259 259 if njobs:
260 260 plural = {1:''}.setdefault(njobs,'s')
261 261 print 'Flushing %s %s job%s.' % (njobs,name,plural)
262 262 group[:] = []
263 263 return True
264 264
265 265 def _status_new(self):
266 266 """Print the status of newly finished jobs.
267 267
268 268 Return True if any new jobs are reported.
269 269
270 270 This call resets its own state every time, so it only reports jobs
271 271 which have finished since the last time it was called."""
272 272
273 273 self._update_status()
274 274 new_comp = self._group_report(self._comp_report, 'Completed')
275 275 new_dead = self._group_report(self._dead_report,
276 276 'Dead, call jobs.traceback() for details')
277 277 self._comp_report[:] = []
278 278 self._dead_report[:] = []
279 279 return new_comp or new_dead
280 280
281 281 def status(self,verbose=0):
282 282 """Print a status of all jobs currently being managed."""
283 283
284 284 self._update_status()
285 285 self._group_report(self.running,'Running')
286 286 self._group_report(self.completed,'Completed')
287 287 self._group_report(self.dead,'Dead')
288 288 # Also flush the report queues
289 289 self._comp_report[:] = []
290 290 self._dead_report[:] = []
291 291
292 292 def remove(self,num):
293 293 """Remove a finished (completed or dead) job."""
294 294
295 295 try:
296 296 job = self.all[num]
297 297 except KeyError:
298 298 error('Job #%s not found' % num)
299 299 else:
300 300 stat_code = job.stat_code
301 301 if stat_code == self._s_running:
302 302 error('Job #%s is still running, it can not be removed.' % num)
303 303 return
304 304 elif stat_code == self._s_completed:
305 305 self.completed.remove(job)
306 306 elif stat_code == self._s_dead:
307 307 self.dead.remove(job)
308 308
309 309 def flush(self):
310 310 """Flush all finished jobs (completed and dead) from lists.
311 311
312 312 Running jobs are never flushed.
313 313
314 314 It first calls _status_new(), to update info. If any jobs have
315 315 completed since the last _status_new() call, the flush operation
316 316 aborts."""
317 317
318 318 # Remove the finished jobs from the master dict
319 319 alljobs = self.all
320 320 for job in self.completed+self.dead:
321 321 del(alljobs[job.num])
322 322
323 323 # Now flush these lists completely
324 324 fl_comp = self._group_flush(self.completed, 'Completed')
325 325 fl_dead = self._group_flush(self.dead, 'Dead')
326 326 if not (fl_comp or fl_dead):
327 327 print 'No jobs to flush.'
328 328
329 329 def result(self,num):
330 330 """result(N) -> return the result of job N."""
331 331 try:
332 332 return self.all[num].result
333 333 except KeyError:
334 334 error('Job #%s not found' % num)
335 335
336 336 def _traceback(self, job):
337 337 num = job if isinstance(job, int) else job.num
338 338 try:
339 339 self.all[num].traceback()
340 340 except KeyError:
341 341 error('Job #%s not found' % num)
342 342
343 343 def traceback(self, job=None):
344 344 if job is None:
345 345 self._update_status()
346 346 for deadjob in self.dead:
347 347 print "Traceback for: %r" % deadjob
348 348 self._traceback(deadjob)
349 349 print
350 350 else:
351 351 self._traceback(job)
352 352
353 353
354 354 class BackgroundJobBase(threading.Thread):
355 355 """Base class to build BackgroundJob classes.
356 356
357 357 The derived classes must implement:
358 358
359 359 - Their own __init__, since the one here raises NotImplementedError. The
360 360 derived constructor must call self._init() at the end, to provide common
361 361 initialization.
362 362
363 363 - A strform attribute used in calls to __str__.
364 364
365 365 - A call() method, which will make the actual execution call and must
366 366 return a value to be held in the 'result' field of the job object."""
367 367
368 368 # Class constants for status, in string and as numerical codes (when
369 369 # updating jobs lists, we don't want to do string comparisons). This will
370 370 # be done at every user prompt, so it has to be as fast as possible
371 371 stat_created = 'Created'; stat_created_c = 0
372 372 stat_running = 'Running'; stat_running_c = 1
373 373 stat_completed = 'Completed'; stat_completed_c = 2
374 374 stat_dead = 'Dead (Exception), call jobs.traceback() for details'
375 375 stat_dead_c = -1
376 376
377 377 def __init__(self):
378 378 raise NotImplementedError("This class can not be instantiated directly.")
379 379
380 380 def _init(self):
381 381 """Common initialization for all BackgroundJob objects"""
382 382
383 383 for attr in ['call','strform']:
384 384 assert hasattr(self,attr), "Missing attribute <%s>" % attr
385 385
386 386 # The num tag can be set by an external job manager
387 387 self.num = None
388 388
389 389 self.status = BackgroundJobBase.stat_created
390 390 self.stat_code = BackgroundJobBase.stat_created_c
391 391 self.finished = False
392 392 self.result = '<BackgroundJob has not completed>'
393 393
394 394 # reuse the ipython traceback handler if we can get to it, otherwise
395 395 # make a new one
396 396 try:
397 397 make_tb = get_ipython().InteractiveTB.text
398 398 except:
399 399 make_tb = AutoFormattedTB(mode = 'Context',
400 400 color_scheme='NoColor',
401 401 tb_offset = 1).text
402 402 # Note that the actual API for text() requires the three args to be
403 403 # passed in, so we wrap it in a simple lambda.
404 404 self._make_tb = lambda : make_tb(None, None, None)
405 405
406 406 # Hold a formatted traceback if one is generated.
407 407 self._tb = None
408 408
409 409 threading.Thread.__init__(self)
410 410
411 411 def __str__(self):
412 412 return self.strform
413 413
414 414 def __repr__(self):
415 415 return '<BackgroundJob #%d: %s>' % (self.num, self.strform)
416 416
417 417 def traceback(self):
418 418 print self._tb
419 419
420 420 def run(self):
421 421 try:
422 422 self.status = BackgroundJobBase.stat_running
423 423 self.stat_code = BackgroundJobBase.stat_running_c
424 424 self.result = self.call()
425 425 except:
426 426 self.status = BackgroundJobBase.stat_dead
427 427 self.stat_code = BackgroundJobBase.stat_dead_c
428 428 self.finished = None
429 429 self.result = ('<BackgroundJob died, call jobs.traceback() for details>')
430 430 self._tb = self._make_tb()
431 431 else:
432 432 self.status = BackgroundJobBase.stat_completed
433 433 self.stat_code = BackgroundJobBase.stat_completed_c
434 434 self.finished = True
435 435
436 436
437 437 class BackgroundJobExpr(BackgroundJobBase):
438 438 """Evaluate an expression as a background job (uses a separate thread)."""
439 439
440 440 def __init__(self, expression, glob=None, loc=None):
441 441 """Create a new job from a string which can be fed to eval().
442 442
443 443 global/locals dicts can be provided, which will be passed to the eval
444 444 call."""
445 445
446 446 # fail immediately if the given expression can't be compiled
447 447 self.code = compile(expression,'<BackgroundJob compilation>','eval')
448 448
449 449 glob = {} if glob is None else glob
450 450 loc = {} if loc is None else loc
451 451 self.expression = self.strform = expression
452 452 self.glob = glob
453 453 self.loc = loc
454 454 self._init()
455 455
456 456 def call(self):
457 457 return eval(self.code,self.glob,self.loc)
458 458
459 459
460 460 class BackgroundJobFunc(BackgroundJobBase):
461 461 """Run a function call as a background job (uses a separate thread)."""
462 462
463 463 def __init__(self, func, *args, **kwargs):
464 464 """Create a new job from a callable object.
465 465
466 466 Any positional arguments and keyword args given to this constructor
467 467 after the initial callable are passed directly to it."""
468 468
469 469 if not callable(func):
470 470 raise TypeError(
471 471 'first argument to BackgroundJobFunc must be callable')
472 472
473 473 self.func = func
474 474 self.args = args
475 475 self.kwargs = kwargs
476 476 # The string form will only include the function passed, because
477 477 # generating string representations of the arguments is a potentially
478 478 # _very_ expensive operation (e.g. with large arrays).
479 479 self.strform = str(func)
480 480 self._init()
481 481
482 482 def call(self):
483 483 return self.func(*self.args, **self.kwargs)
@@ -1,56 +1,55 b''
1 1 """ Utilities for accessing the platform's clipboard.
2 2 """
3 3
4 4 import subprocess
5 import sys
6 5
7 6 from IPython.core.error import TryNext
8 7 import IPython.utils.py3compat as py3compat
9 8
10 9 def win32_clipboard_get():
11 10 """ Get the current clipboard's text on Windows.
12 11
13 12 Requires Mark Hammond's pywin32 extensions.
14 13 """
15 14 try:
16 15 import win32clipboard
17 16 except ImportError:
18 17 raise TryNext("Getting text from the clipboard requires the pywin32 "
19 18 "extensions: http://sourceforge.net/projects/pywin32/")
20 19 win32clipboard.OpenClipboard()
21 20 text = win32clipboard.GetClipboardData(win32clipboard.CF_TEXT)
22 21 # FIXME: convert \r\n to \n?
23 22 win32clipboard.CloseClipboard()
24 23 return text
25 24
26 25 def osx_clipboard_get():
27 26 """ Get the clipboard's text on OS X.
28 27 """
29 28 p = subprocess.Popen(['pbpaste', '-Prefer', 'ascii'],
30 29 stdout=subprocess.PIPE)
31 30 text, stderr = p.communicate()
32 31 # Text comes in with old Mac \r line endings. Change them to \n.
33 32 text = text.replace(b'\r', b'\n')
34 33 text = py3compat.cast_unicode(text, py3compat.DEFAULT_ENCODING)
35 34 return text
36 35
37 36 def tkinter_clipboard_get():
38 37 """ Get the clipboard's text using Tkinter.
39 38
40 39 This is the default on systems that are not Windows or OS X. It may
41 40 interfere with other UI toolkits and should be replaced with an
42 41 implementation that uses that toolkit.
43 42 """
44 43 try:
45 44 import Tkinter
46 45 except ImportError:
47 46 raise TryNext("Getting text from the clipboard on this platform "
48 47 "requires Tkinter.")
49 48 root = Tkinter.Tk()
50 49 root.withdraw()
51 50 text = root.clipboard_get()
52 51 root.destroy()
53 52 text = py3compat.cast_unicode(text, py3compat.DEFAULT_ENCODING)
54 53 return text
55 54
56 55
@@ -1,583 +1,582 b''
1 1 """Module for interactive demos using IPython.
2 2
3 3 This module implements a few classes for running Python scripts interactively
4 4 in IPython for demonstrations. With very simple markup (a few tags in
5 5 comments), you can control points where the script stops executing and returns
6 6 control to IPython.
7 7
8 8
9 9 Provided classes
10 10 ----------------
11 11
12 12 The classes are (see their docstrings for further details):
13 13
14 14 - Demo: pure python demos
15 15
16 16 - IPythonDemo: demos with input to be processed by IPython as if it had been
17 17 typed interactively (so magics work, as well as any other special syntax you
18 18 may have added via input prefilters).
19 19
20 20 - LineDemo: single-line version of the Demo class. These demos are executed
21 21 one line at a time, and require no markup.
22 22
23 23 - IPythonLineDemo: IPython version of the LineDemo class (the demo is
24 24 executed a line at a time, but processed via IPython).
25 25
26 26 - ClearMixin: mixin to make Demo classes with less visual clutter. It
27 27 declares an empty marquee and a pre_cmd that clears the screen before each
28 28 block (see Subclassing below).
29 29
30 30 - ClearDemo, ClearIPDemo: mixin-enabled versions of the Demo and IPythonDemo
31 31 classes.
32 32
33 33 Inheritance diagram:
34 34
35 35 .. inheritance-diagram:: IPython.lib.demo
36 36 :parts: 3
37 37
38 38 Subclassing
39 39 -----------
40 40
41 41 The classes here all include a few methods meant to make customization by
42 42 subclassing more convenient. Their docstrings below have some more details:
43 43
44 44 - marquee(): generates a marquee to provide visible on-screen markers at each
45 45 block start and end.
46 46
47 47 - pre_cmd(): run right before the execution of each block.
48 48
49 49 - post_cmd(): run right after the execution of each block. If the block
50 50 raises an exception, this is NOT called.
51 51
52 52
53 53 Operation
54 54 ---------
55 55
56 56 The file is run in its own empty namespace (though you can pass it a string of
57 57 arguments as if in a command line environment, and it will see those as
58 58 sys.argv). But at each stop, the global IPython namespace is updated with the
59 59 current internal demo namespace, so you can work interactively with the data
60 60 accumulated so far.
61 61
62 62 By default, each block of code is printed (with syntax highlighting) before
63 63 executing it and you have to confirm execution. This is intended to show the
64 64 code to an audience first so you can discuss it, and only proceed with
65 65 execution once you agree. There are a few tags which allow you to modify this
66 66 behavior.
67 67
68 68 The supported tags are:
69 69
70 70 # <demo> stop
71 71
72 72 Defines block boundaries, the points where IPython stops execution of the
73 73 file and returns to the interactive prompt.
74 74
75 75 You can optionally mark the stop tag with extra dashes before and after the
76 76 word 'stop', to help visually distinguish the blocks in a text editor:
77 77
78 78 # <demo> --- stop ---
79 79
80 80
81 81 # <demo> silent
82 82
83 83 Make a block execute silently (and hence automatically). Typically used in
84 84 cases where you have some boilerplate or initialization code which you need
85 85 executed but do not want to be seen in the demo.
86 86
87 87 # <demo> auto
88 88
89 89 Make a block execute automatically, but still being printed. Useful for
90 90 simple code which does not warrant discussion, since it avoids the extra
91 91 manual confirmation.
92 92
93 93 # <demo> auto_all
94 94
95 95 This tag can _only_ be in the first block, and if given it overrides the
96 96 individual auto tags to make the whole demo fully automatic (no block asks
97 97 for confirmation). It can also be given at creation time (or the attribute
98 98 set later) to override what's in the file.
99 99
100 100 While _any_ python file can be run as a Demo instance, if there are no stop
101 101 tags the whole file will run in a single block (no different that calling
102 102 first %pycat and then %run). The minimal markup to make this useful is to
103 103 place a set of stop tags; the other tags are only there to let you fine-tune
104 104 the execution.
105 105
106 106 This is probably best explained with the simple example file below. You can
107 107 copy this into a file named ex_demo.py, and try running it via::
108 108
109 109 from IPython.demo import Demo
110 110 d = Demo('ex_demo.py')
111 111 d()
112 112
113 113 Each time you call the demo object, it runs the next block. The demo object
114 114 has a few useful methods for navigation, like again(), edit(), jump(), seek()
115 115 and back(). It can be reset for a new run via reset() or reloaded from disk
116 116 (in case you've edited the source) via reload(). See their docstrings below.
117 117
118 118 Note: To make this simpler to explore, a file called "demo-exercizer.py" has
119 119 been added to the "docs/examples/core" directory. Just cd to this directory in
120 120 an IPython session, and type::
121 121
122 122 %run demo-exercizer.py
123 123
124 124 and then follow the directions.
125 125
126 126 Example
127 127 -------
128 128
129 129 The following is a very simple example of a valid demo file.
130 130
131 131 ::
132 132
133 133 #################### EXAMPLE DEMO <ex_demo.py> ###############################
134 134 '''A simple interactive demo to illustrate the use of IPython's Demo class.'''
135 135
136 136 print 'Hello, welcome to an interactive IPython demo.'
137 137
138 138 # The mark below defines a block boundary, which is a point where IPython will
139 139 # stop execution and return to the interactive prompt. The dashes are actually
140 140 # optional and used only as a visual aid to clearly separate blocks while
141 141 # editing the demo code.
142 142 # <demo> stop
143 143
144 144 x = 1
145 145 y = 2
146 146
147 147 # <demo> stop
148 148
149 149 # the mark below makes this block as silent
150 150 # <demo> silent
151 151
152 152 print 'This is a silent block, which gets executed but not printed.'
153 153
154 154 # <demo> stop
155 155 # <demo> auto
156 156 print 'This is an automatic block.'
157 157 print 'It is executed without asking for confirmation, but printed.'
158 158 z = x+y
159 159
160 160 print 'z=',x
161 161
162 162 # <demo> stop
163 163 # This is just another normal block.
164 164 print 'z is now:', z
165 165
166 166 print 'bye!'
167 167 ################### END EXAMPLE DEMO <ex_demo.py> ############################
168 168 """
169 169
170 170 from __future__ import unicode_literals
171 171
172 172 #*****************************************************************************
173 173 # Copyright (C) 2005-2006 Fernando Perez. <Fernando.Perez@colorado.edu>
174 174 #
175 175 # Distributed under the terms of the BSD License. The full license is in
176 176 # the file COPYING, distributed as part of this software.
177 177 #
178 178 #*****************************************************************************
179 179 from __future__ import print_function
180 180
181 181 import os
182 182 import re
183 183 import shlex
184 184 import sys
185 185
186 from IPython.utils.PyColorize import Parser
187 186 from IPython.utils import io
188 from IPython.utils.io import file_read, file_readlines
187 from IPython.utils.io import file_read
189 188 from IPython.utils.text import marquee
190 189 from IPython.utils import openpy
191 190 __all__ = ['Demo','IPythonDemo','LineDemo','IPythonLineDemo','DemoError']
192 191
193 192 class DemoError(Exception): pass
194 193
195 194 def re_mark(mark):
196 195 return re.compile(r'^\s*#\s+<demo>\s+%s\s*$' % mark,re.MULTILINE)
197 196
198 197 class Demo(object):
199 198
200 199 re_stop = re_mark('-*\s?stop\s?-*')
201 200 re_silent = re_mark('silent')
202 201 re_auto = re_mark('auto')
203 202 re_auto_all = re_mark('auto_all')
204 203
205 204 def __init__(self,src,title='',arg_str='',auto_all=None):
206 205 """Make a new demo object. To run the demo, simply call the object.
207 206
208 207 See the module docstring for full details and an example (you can use
209 208 IPython.Demo? in IPython to see it).
210 209
211 210 Inputs:
212 211
213 212 - src is either a file, or file-like object, or a
214 213 string that can be resolved to a filename.
215 214
216 215 Optional inputs:
217 216
218 217 - title: a string to use as the demo name. Of most use when the demo
219 218 you are making comes from an object that has no filename, or if you
220 219 want an alternate denotation distinct from the filename.
221 220
222 221 - arg_str(''): a string of arguments, internally converted to a list
223 222 just like sys.argv, so the demo script can see a similar
224 223 environment.
225 224
226 225 - auto_all(None): global flag to run all blocks automatically without
227 226 confirmation. This attribute overrides the block-level tags and
228 227 applies to the whole demo. It is an attribute of the object, and
229 228 can be changed at runtime simply by reassigning it to a boolean
230 229 value.
231 230 """
232 231 if hasattr(src, "read"):
233 232 # It seems to be a file or a file-like object
234 233 self.fname = "from a file-like object"
235 234 if title == '':
236 235 self.title = "from a file-like object"
237 236 else:
238 237 self.title = title
239 238 else:
240 239 # Assume it's a string or something that can be converted to one
241 240 self.fname = src
242 241 if title == '':
243 242 (filepath, filename) = os.path.split(src)
244 243 self.title = filename
245 244 else:
246 245 self.title = title
247 246 self.sys_argv = [src] + shlex.split(arg_str)
248 247 self.auto_all = auto_all
249 248 self.src = src
250 249
251 250 # get a few things from ipython. While it's a bit ugly design-wise,
252 251 # it ensures that things like color scheme and the like are always in
253 252 # sync with the ipython mode being used. This class is only meant to
254 253 # be used inside ipython anyways, so it's OK.
255 254 ip = get_ipython() # this is in builtins whenever IPython is running
256 255 self.ip_ns = ip.user_ns
257 256 self.ip_colorize = ip.pycolorize
258 257 self.ip_showtb = ip.showtraceback
259 258 self.ip_run_cell = ip.run_cell
260 259 self.shell = ip
261 260
262 261 # load user data and initialize data structures
263 262 self.reload()
264 263
265 264 def fload(self):
266 265 """Load file object."""
267 266 # read data and parse into blocks
268 267 if hasattr(self, 'fobj') and self.fobj is not None:
269 268 self.fobj.close()
270 269 if hasattr(self.src, "read"):
271 270 # It seems to be a file or a file-like object
272 271 self.fobj = self.src
273 272 else:
274 273 # Assume it's a string or something that can be converted to one
275 274 self.fobj = openpy.open(self.fname)
276 275
277 276 def reload(self):
278 277 """Reload source from disk and initialize state."""
279 278 self.fload()
280 279
281 280 self.src = "".join(openpy.strip_encoding_cookie(self.fobj))
282 281 src_b = [b.strip() for b in self.re_stop.split(self.src) if b]
283 282 self._silent = [bool(self.re_silent.findall(b)) for b in src_b]
284 283 self._auto = [bool(self.re_auto.findall(b)) for b in src_b]
285 284
286 285 # if auto_all is not given (def. None), we read it from the file
287 286 if self.auto_all is None:
288 287 self.auto_all = bool(self.re_auto_all.findall(src_b[0]))
289 288 else:
290 289 self.auto_all = bool(self.auto_all)
291 290
292 291 # Clean the sources from all markup so it doesn't get displayed when
293 292 # running the demo
294 293 src_blocks = []
295 294 auto_strip = lambda s: self.re_auto.sub('',s)
296 295 for i,b in enumerate(src_b):
297 296 if self._auto[i]:
298 297 src_blocks.append(auto_strip(b))
299 298 else:
300 299 src_blocks.append(b)
301 300 # remove the auto_all marker
302 301 src_blocks[0] = self.re_auto_all.sub('',src_blocks[0])
303 302
304 303 self.nblocks = len(src_blocks)
305 304 self.src_blocks = src_blocks
306 305
307 306 # also build syntax-highlighted source
308 307 self.src_blocks_colored = map(self.ip_colorize,self.src_blocks)
309 308
310 309 # ensure clean namespace and seek offset
311 310 self.reset()
312 311
313 312 def reset(self):
314 313 """Reset the namespace and seek pointer to restart the demo"""
315 314 self.user_ns = {}
316 315 self.finished = False
317 316 self.block_index = 0
318 317
319 318 def _validate_index(self,index):
320 319 if index<0 or index>=self.nblocks:
321 320 raise ValueError('invalid block index %s' % index)
322 321
323 322 def _get_index(self,index):
324 323 """Get the current block index, validating and checking status.
325 324
326 325 Returns None if the demo is finished"""
327 326
328 327 if index is None:
329 328 if self.finished:
330 329 print('Demo finished. Use <demo_name>.reset() if you want to rerun it.', file=io.stdout)
331 330 return None
332 331 index = self.block_index
333 332 else:
334 333 self._validate_index(index)
335 334 return index
336 335
337 336 def seek(self,index):
338 337 """Move the current seek pointer to the given block.
339 338
340 339 You can use negative indices to seek from the end, with identical
341 340 semantics to those of Python lists."""
342 341 if index<0:
343 342 index = self.nblocks + index
344 343 self._validate_index(index)
345 344 self.block_index = index
346 345 self.finished = False
347 346
348 347 def back(self,num=1):
349 348 """Move the seek pointer back num blocks (default is 1)."""
350 349 self.seek(self.block_index-num)
351 350
352 351 def jump(self,num=1):
353 352 """Jump a given number of blocks relative to the current one.
354 353
355 354 The offset can be positive or negative, defaults to 1."""
356 355 self.seek(self.block_index+num)
357 356
358 357 def again(self):
359 358 """Move the seek pointer back one block and re-execute."""
360 359 self.back(1)
361 360 self()
362 361
363 362 def edit(self,index=None):
364 363 """Edit a block.
365 364
366 365 If no number is given, use the last block executed.
367 366
368 367 This edits the in-memory copy of the demo, it does NOT modify the
369 368 original source file. If you want to do that, simply open the file in
370 369 an editor and use reload() when you make changes to the file. This
371 370 method is meant to let you change a block during a demonstration for
372 371 explanatory purposes, without damaging your original script."""
373 372
374 373 index = self._get_index(index)
375 374 if index is None:
376 375 return
377 376 # decrease the index by one (unless we're at the very beginning), so
378 377 # that the default demo.edit() call opens up the sblock we've last run
379 378 if index>0:
380 379 index -= 1
381 380
382 381 filename = self.shell.mktempfile(self.src_blocks[index])
383 382 self.shell.hooks.editor(filename,1)
384 383 new_block = file_read(filename)
385 384 # update the source and colored block
386 385 self.src_blocks[index] = new_block
387 386 self.src_blocks_colored[index] = self.ip_colorize(new_block)
388 387 self.block_index = index
389 388 # call to run with the newly edited index
390 389 self()
391 390
392 391 def show(self,index=None):
393 392 """Show a single block on screen"""
394 393
395 394 index = self._get_index(index)
396 395 if index is None:
397 396 return
398 397
399 398 print(self.marquee('<%s> block # %s (%s remaining)' %
400 399 (self.title,index,self.nblocks-index-1)), file=io.stdout)
401 400 print((self.src_blocks_colored[index]), file=io.stdout)
402 401 sys.stdout.flush()
403 402
404 403 def show_all(self):
405 404 """Show entire demo on screen, block by block"""
406 405
407 406 fname = self.title
408 407 title = self.title
409 408 nblocks = self.nblocks
410 409 silent = self._silent
411 410 marquee = self.marquee
412 411 for index,block in enumerate(self.src_blocks_colored):
413 412 if silent[index]:
414 413 print(marquee('<%s> SILENT block # %s (%s remaining)' %
415 414 (title,index,nblocks-index-1)), file=io.stdout)
416 415 else:
417 416 print(marquee('<%s> block # %s (%s remaining)' %
418 417 (title,index,nblocks-index-1)), file=io.stdout)
419 418 print(block, end=' ', file=io.stdout)
420 419 sys.stdout.flush()
421 420
422 421 def run_cell(self,source):
423 422 """Execute a string with one or more lines of code"""
424 423
425 424 exec source in self.user_ns
426 425
427 426 def __call__(self,index=None):
428 427 """run a block of the demo.
429 428
430 429 If index is given, it should be an integer >=1 and <= nblocks. This
431 430 means that the calling convention is one off from typical Python
432 431 lists. The reason for the inconsistency is that the demo always
433 432 prints 'Block n/N, and N is the total, so it would be very odd to use
434 433 zero-indexing here."""
435 434
436 435 index = self._get_index(index)
437 436 if index is None:
438 437 return
439 438 try:
440 439 marquee = self.marquee
441 440 next_block = self.src_blocks[index]
442 441 self.block_index += 1
443 442 if self._silent[index]:
444 443 print(marquee('Executing silent block # %s (%s remaining)' %
445 444 (index,self.nblocks-index-1)), file=io.stdout)
446 445 else:
447 446 self.pre_cmd()
448 447 self.show(index)
449 448 if self.auto_all or self._auto[index]:
450 449 print(marquee('output:'), file=io.stdout)
451 450 else:
452 451 print(marquee('Press <q> to quit, <Enter> to execute...'), end=' ', file=io.stdout)
453 452 ans = raw_input().strip()
454 453 if ans:
455 454 print(marquee('Block NOT executed'), file=io.stdout)
456 455 return
457 456 try:
458 457 save_argv = sys.argv
459 458 sys.argv = self.sys_argv
460 459 self.run_cell(next_block)
461 460 self.post_cmd()
462 461 finally:
463 462 sys.argv = save_argv
464 463
465 464 except:
466 465 self.ip_showtb(filename=self.fname)
467 466 else:
468 467 self.ip_ns.update(self.user_ns)
469 468
470 469 if self.block_index == self.nblocks:
471 470 mq1 = self.marquee('END OF DEMO')
472 471 if mq1:
473 472 # avoid spurious print >>io.stdout,s if empty marquees are used
474 473 print(file=io.stdout)
475 474 print(mq1, file=io.stdout)
476 475 print(self.marquee('Use <demo_name>.reset() if you want to rerun it.'), file=io.stdout)
477 476 self.finished = True
478 477
479 478 # These methods are meant to be overridden by subclasses who may wish to
480 479 # customize the behavior of of their demos.
481 480 def marquee(self,txt='',width=78,mark='*'):
482 481 """Return the input string centered in a 'marquee'."""
483 482 return marquee(txt,width,mark)
484 483
485 484 def pre_cmd(self):
486 485 """Method called before executing each block."""
487 486 pass
488 487
489 488 def post_cmd(self):
490 489 """Method called after executing each block."""
491 490 pass
492 491
493 492
494 493 class IPythonDemo(Demo):
495 494 """Class for interactive demos with IPython's input processing applied.
496 495
497 496 This subclasses Demo, but instead of executing each block by the Python
498 497 interpreter (via exec), it actually calls IPython on it, so that any input
499 498 filters which may be in place are applied to the input block.
500 499
501 500 If you have an interactive environment which exposes special input
502 501 processing, you can use this class instead to write demo scripts which
503 502 operate exactly as if you had typed them interactively. The default Demo
504 503 class requires the input to be valid, pure Python code.
505 504 """
506 505
507 506 def run_cell(self,source):
508 507 """Execute a string with one or more lines of code"""
509 508
510 509 self.shell.run_cell(source)
511 510
512 511 class LineDemo(Demo):
513 512 """Demo where each line is executed as a separate block.
514 513
515 514 The input script should be valid Python code.
516 515
517 516 This class doesn't require any markup at all, and it's meant for simple
518 517 scripts (with no nesting or any kind of indentation) which consist of
519 518 multiple lines of input to be executed, one at a time, as if they had been
520 519 typed in the interactive prompt.
521 520
522 521 Note: the input can not have *any* indentation, which means that only
523 522 single-lines of input are accepted, not even function definitions are
524 523 valid."""
525 524
526 525 def reload(self):
527 526 """Reload source from disk and initialize state."""
528 527 # read data and parse into blocks
529 528 self.fload()
530 529 lines = self.fobj.readlines()
531 530 src_b = [l for l in lines if l.strip()]
532 531 nblocks = len(src_b)
533 532 self.src = ''.join(lines)
534 533 self._silent = [False]*nblocks
535 534 self._auto = [True]*nblocks
536 535 self.auto_all = True
537 536 self.nblocks = nblocks
538 537 self.src_blocks = src_b
539 538
540 539 # also build syntax-highlighted source
541 540 self.src_blocks_colored = map(self.ip_colorize,self.src_blocks)
542 541
543 542 # ensure clean namespace and seek offset
544 543 self.reset()
545 544
546 545
547 546 class IPythonLineDemo(IPythonDemo,LineDemo):
548 547 """Variant of the LineDemo class whose input is processed by IPython."""
549 548 pass
550 549
551 550
552 551 class ClearMixin(object):
553 552 """Use this mixin to make Demo classes with less visual clutter.
554 553
555 554 Demos using this mixin will clear the screen before every block and use
556 555 blank marquees.
557 556
558 557 Note that in order for the methods defined here to actually override those
559 558 of the classes it's mixed with, it must go /first/ in the inheritance
560 559 tree. For example:
561 560
562 561 class ClearIPDemo(ClearMixin,IPythonDemo): pass
563 562
564 563 will provide an IPythonDemo class with the mixin's features.
565 564 """
566 565
567 566 def marquee(self,txt='',width=78,mark='*'):
568 567 """Blank marquee that returns '' no matter what the input."""
569 568 return ''
570 569
571 570 def pre_cmd(self):
572 571 """Method called before executing each block.
573 572
574 573 This one simply clears the screen."""
575 574 from IPython.utils.terminal import term_clear
576 575 term_clear()
577 576
578 577 class ClearDemo(ClearMixin,Demo):
579 578 pass
580 579
581 580
582 581 class ClearIPDemo(ClearMixin,IPythonDemo):
583 582 pass
@@ -1,165 +1,163 b''
1 1 # encoding: utf-8
2 2
3 3 """
4 4 Enable wxPython to be used interacive by setting PyOS_InputHook.
5 5
6 6 Authors: Robin Dunn, Brian Granger, Ondrej Certik
7 7 """
8 8
9 9 #-----------------------------------------------------------------------------
10 10 # Copyright (C) 2008-2011 The IPython Development Team
11 11 #
12 12 # Distributed under the terms of the BSD License. The full license is in
13 13 # the file COPYING, distributed as part of this software.
14 14 #-----------------------------------------------------------------------------
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Imports
18 18 #-----------------------------------------------------------------------------
19 19
20 import os
21 20 import signal
22 import sys
23 21 import time
24 22 from timeit import default_timer as clock
25 23 import wx
26 24
27 25 from IPython.lib.inputhook import stdin_ready
28 26
29 27
30 28 #-----------------------------------------------------------------------------
31 29 # Code
32 30 #-----------------------------------------------------------------------------
33 31
34 32 def inputhook_wx1():
35 33 """Run the wx event loop by processing pending events only.
36 34
37 35 This approach seems to work, but its performance is not great as it
38 36 relies on having PyOS_InputHook called regularly.
39 37 """
40 38 try:
41 39 app = wx.GetApp()
42 40 if app is not None:
43 41 assert wx.Thread_IsMain()
44 42
45 43 # Make a temporary event loop and process system events until
46 44 # there are no more waiting, then allow idle events (which
47 45 # will also deal with pending or posted wx events.)
48 46 evtloop = wx.EventLoop()
49 47 ea = wx.EventLoopActivator(evtloop)
50 48 while evtloop.Pending():
51 49 evtloop.Dispatch()
52 50 app.ProcessIdle()
53 51 del ea
54 52 except KeyboardInterrupt:
55 53 pass
56 54 return 0
57 55
58 56 class EventLoopTimer(wx.Timer):
59 57
60 58 def __init__(self, func):
61 59 self.func = func
62 60 wx.Timer.__init__(self)
63 61
64 62 def Notify(self):
65 63 self.func()
66 64
67 65 class EventLoopRunner(object):
68 66
69 67 def Run(self, time):
70 68 self.evtloop = wx.EventLoop()
71 69 self.timer = EventLoopTimer(self.check_stdin)
72 70 self.timer.Start(time)
73 71 self.evtloop.Run()
74 72
75 73 def check_stdin(self):
76 74 if stdin_ready():
77 75 self.timer.Stop()
78 76 self.evtloop.Exit()
79 77
80 78 def inputhook_wx2():
81 79 """Run the wx event loop, polling for stdin.
82 80
83 81 This version runs the wx eventloop for an undetermined amount of time,
84 82 during which it periodically checks to see if anything is ready on
85 83 stdin. If anything is ready on stdin, the event loop exits.
86 84
87 85 The argument to elr.Run controls how often the event loop looks at stdin.
88 86 This determines the responsiveness at the keyboard. A setting of 1000
89 87 enables a user to type at most 1 char per second. I have found that a
90 88 setting of 10 gives good keyboard response. We can shorten it further,
91 89 but eventually performance would suffer from calling select/kbhit too
92 90 often.
93 91 """
94 92 try:
95 93 app = wx.GetApp()
96 94 if app is not None:
97 95 assert wx.Thread_IsMain()
98 96 elr = EventLoopRunner()
99 97 # As this time is made shorter, keyboard response improves, but idle
100 98 # CPU load goes up. 10 ms seems like a good compromise.
101 99 elr.Run(time=10) # CHANGE time here to control polling interval
102 100 except KeyboardInterrupt:
103 101 pass
104 102 return 0
105 103
106 104 def inputhook_wx3():
107 105 """Run the wx event loop by processing pending events only.
108 106
109 107 This is like inputhook_wx1, but it keeps processing pending events
110 108 until stdin is ready. After processing all pending events, a call to
111 109 time.sleep is inserted. This is needed, otherwise, CPU usage is at 100%.
112 110 This sleep time should be tuned though for best performance.
113 111 """
114 112 # We need to protect against a user pressing Control-C when IPython is
115 113 # idle and this is running. We trap KeyboardInterrupt and pass.
116 114 try:
117 115 app = wx.GetApp()
118 116 if app is not None:
119 117 assert wx.Thread_IsMain()
120 118
121 119 # The import of wx on Linux sets the handler for signal.SIGINT
122 120 # to 0. This is a bug in wx or gtk. We fix by just setting it
123 121 # back to the Python default.
124 122 if not callable(signal.getsignal(signal.SIGINT)):
125 123 signal.signal(signal.SIGINT, signal.default_int_handler)
126 124
127 125 evtloop = wx.EventLoop()
128 126 ea = wx.EventLoopActivator(evtloop)
129 127 t = clock()
130 128 while not stdin_ready():
131 129 while evtloop.Pending():
132 130 t = clock()
133 131 evtloop.Dispatch()
134 132 app.ProcessIdle()
135 133 # We need to sleep at this point to keep the idle CPU load
136 134 # low. However, if sleep to long, GUI response is poor. As
137 135 # a compromise, we watch how often GUI events are being processed
138 136 # and switch between a short and long sleep time. Here are some
139 137 # stats useful in helping to tune this.
140 138 # time CPU load
141 139 # 0.001 13%
142 140 # 0.005 3%
143 141 # 0.01 1.5%
144 142 # 0.05 0.5%
145 143 used_time = clock() - t
146 144 if used_time > 5*60.0:
147 145 # print 'Sleep for 5 s' # dbg
148 146 time.sleep(5.0)
149 147 elif used_time > 10.0:
150 148 # print 'Sleep for 1 s' # dbg
151 149 time.sleep(1.0)
152 150 elif used_time > 0.1:
153 151 # Few GUI events coming in, so we can sleep longer
154 152 # print 'Sleep for 0.05 s' # dbg
155 153 time.sleep(0.05)
156 154 else:
157 155 # Many GUI events coming in, so sleep only very little
158 156 time.sleep(0.001)
159 157 del ea
160 158 except KeyboardInterrupt:
161 159 pass
162 160 return 0
163 161
164 162 # This is our default implementation
165 163 inputhook_wx = inputhook_wx3
@@ -1,252 +1,252 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Tools for handling LaTeX.
3 3
4 4 Authors:
5 5
6 6 * Brian Granger
7 7 """
8 8 #-----------------------------------------------------------------------------
9 9 # Copyright (C) 2010 IPython Development Team.
10 10 #
11 11 # Distributed under the terms of the Modified BSD License.
12 12 #
13 13 # The full license is in the file COPYING.txt, distributed with this software.
14 14 #-----------------------------------------------------------------------------
15 15
16 16 #-----------------------------------------------------------------------------
17 17 # Imports
18 18 #-----------------------------------------------------------------------------
19 19
20 20 from io import BytesIO
21 21 from base64 import encodestring
22 22 import os
23 23 import tempfile
24 24 import shutil
25 25 import subprocess
26 26
27 27 from IPython.utils.process import find_cmd, FindCmdError
28 28 from IPython.config.configurable import SingletonConfigurable
29 from IPython.utils.traitlets import Instance, List, CBool, CUnicode
29 from IPython.utils.traitlets import List, CBool, CUnicode
30 30 from IPython.utils.py3compat import bytes_to_str
31 31
32 32 #-----------------------------------------------------------------------------
33 33 # Tools
34 34 #-----------------------------------------------------------------------------
35 35
36 36
37 37 class LaTeXTool(SingletonConfigurable):
38 38 """An object to store configuration of the LaTeX tool."""
39 39
40 40 backends = List(
41 41 CUnicode, ["matplotlib", "dvipng"],
42 42 help="Preferred backend to draw LaTeX math equations. "
43 43 "Backends in the list are checked one by one and the first "
44 44 "usable one is used. Note that `matplotlib` backend "
45 45 "is usable only for inline style equations. To draw "
46 46 "display style equations, `dvipng` backend must be specified. ",
47 47 # It is a List instead of Enum, to make configuration more
48 48 # flexible. For example, to use matplotlib mainly but dvipng
49 49 # for display style, the default ["matplotlib", "dvipng"] can
50 50 # be used. To NOT use dvipng so that other repr such as
51 51 # unicode pretty printing is used, you can use ["matplotlib"].
52 52 config=True)
53 53
54 54 use_breqn = CBool(
55 55 True,
56 56 help="Use breqn.sty to automatically break long equations. "
57 57 "This configuration takes effect only for dvipng backend.",
58 58 config=True)
59 59
60 60 packages = List(
61 61 ['amsmath', 'amsthm', 'amssymb', 'bm'],
62 62 help="A list of packages to use for dvipng backend. "
63 63 "'breqn' will be automatically appended when use_breqn=True.",
64 64 config=True)
65 65
66 66 preamble = CUnicode(
67 67 help="Additional preamble to use when generating LaTeX source "
68 68 "for dvipng backend.",
69 69 config=True)
70 70
71 71
72 72 def latex_to_png(s, encode=False, backend=None, wrap=False):
73 73 """Render a LaTeX string to PNG.
74 74
75 75 Parameters
76 76 ----------
77 77 s : str
78 78 The raw string containing valid inline LaTeX.
79 79 encode : bool, optional
80 80 Should the PNG data bebase64 encoded to make it JSON'able.
81 81 backend : {matplotlib, dvipng}
82 82 Backend for producing PNG data.
83 83 wrap : bool
84 84 If true, Automatically wrap `s` as a LaTeX equation.
85 85
86 86 None is returned when the backend cannot be used.
87 87
88 88 """
89 89 allowed_backends = LaTeXTool.instance().backends
90 90 if backend is None:
91 91 backend = allowed_backends[0]
92 92 if backend not in allowed_backends:
93 93 return None
94 94 if backend == 'matplotlib':
95 95 f = latex_to_png_mpl
96 96 elif backend == 'dvipng':
97 97 f = latex_to_png_dvipng
98 98 else:
99 99 raise ValueError('No such backend {0}'.format(backend))
100 100 bin_data = f(s, wrap)
101 101 if encode and bin_data:
102 102 bin_data = encodestring(bin_data)
103 103 return bin_data
104 104
105 105
106 106 def latex_to_png_mpl(s, wrap):
107 107 try:
108 108 from matplotlib import mathtext
109 109 except ImportError:
110 110 return None
111 111
112 112 if wrap:
113 113 s = '${0}$'.format(s)
114 114 mt = mathtext.MathTextParser('bitmap')
115 115 f = BytesIO()
116 116 mt.to_png(f, s, fontsize=12)
117 117 return f.getvalue()
118 118
119 119
120 120 def latex_to_png_dvipng(s, wrap):
121 121 try:
122 122 find_cmd('latex')
123 123 find_cmd('dvipng')
124 124 except FindCmdError:
125 125 return None
126 126 try:
127 127 workdir = tempfile.mkdtemp()
128 128 tmpfile = os.path.join(workdir, "tmp.tex")
129 129 dvifile = os.path.join(workdir, "tmp.dvi")
130 130 outfile = os.path.join(workdir, "tmp.png")
131 131
132 132 with open(tmpfile, "w") as f:
133 133 f.writelines(genelatex(s, wrap))
134 134
135 135 with open(os.devnull, 'w') as devnull:
136 136 subprocess.check_call(
137 137 ["latex", "-halt-on-error", tmpfile], cwd=workdir,
138 138 stdout=devnull, stderr=devnull)
139 139
140 140 subprocess.check_call(
141 141 ["dvipng", "-T", "tight", "-x", "1500", "-z", "9",
142 142 "-bg", "transparent", "-o", outfile, dvifile], cwd=workdir,
143 143 stdout=devnull, stderr=devnull)
144 144
145 145 with open(outfile, "rb") as f:
146 146 bin_data = f.read()
147 147 finally:
148 148 shutil.rmtree(workdir)
149 149 return bin_data
150 150
151 151
152 152 def kpsewhich(filename):
153 153 """Invoke kpsewhich command with an argument `filename`."""
154 154 try:
155 155 find_cmd("kpsewhich")
156 156 proc = subprocess.Popen(
157 157 ["kpsewhich", filename],
158 158 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
159 159 (stdout, stderr) = proc.communicate()
160 160 return stdout.strip()
161 161 except FindCmdError:
162 162 pass
163 163
164 164
165 165 def genelatex(body, wrap):
166 166 """Generate LaTeX document for dvipng backend."""
167 167 lt = LaTeXTool.instance()
168 168 breqn = wrap and lt.use_breqn and kpsewhich("breqn.sty")
169 169 yield r'\documentclass{article}'
170 170 packages = lt.packages
171 171 if breqn:
172 172 packages = packages + ['breqn']
173 173 for pack in packages:
174 174 yield r'\usepackage{{{0}}}'.format(pack)
175 175 yield r'\pagestyle{empty}'
176 176 if lt.preamble:
177 177 yield lt.preamble
178 178 yield r'\begin{document}'
179 179 if breqn:
180 180 yield r'\begin{dmath*}'
181 181 yield body
182 182 yield r'\end{dmath*}'
183 183 elif wrap:
184 184 yield '$${0}$$'.format(body)
185 185 else:
186 186 yield body
187 187 yield r'\end{document}'
188 188
189 189
190 190 _data_uri_template_png = """<img src="data:image/png;base64,%s" alt=%s />"""
191 191
192 192 def latex_to_html(s, alt='image'):
193 193 """Render LaTeX to HTML with embedded PNG data using data URIs.
194 194
195 195 Parameters
196 196 ----------
197 197 s : str
198 198 The raw string containing valid inline LateX.
199 199 alt : str
200 200 The alt text to use for the HTML.
201 201 """
202 202 base64_data = bytes_to_str(latex_to_png(s, encode=True), 'ascii')
203 203 if base64_data:
204 204 return _data_uri_template_png % (base64_data, alt)
205 205
206 206
207 207 # From matplotlib, thanks to mdboom. Once this is in matplotlib releases, we
208 208 # will remove.
209 209 def math_to_image(s, filename_or_obj, prop=None, dpi=None, format=None):
210 210 """
211 211 Given a math expression, renders it in a closely-clipped bounding
212 212 box to an image file.
213 213
214 214 *s*
215 215 A math expression. The math portion should be enclosed in
216 216 dollar signs.
217 217
218 218 *filename_or_obj*
219 219 A filepath or writable file-like object to write the image data
220 220 to.
221 221
222 222 *prop*
223 223 If provided, a FontProperties() object describing the size and
224 224 style of the text.
225 225
226 226 *dpi*
227 227 Override the output dpi, otherwise use the default associated
228 228 with the output format.
229 229
230 230 *format*
231 231 The output format, eg. 'svg', 'pdf', 'ps' or 'png'. If not
232 232 provided, will be deduced from the filename.
233 233 """
234 234 from matplotlib import figure
235 235 # backend_agg supports all of the core output formats
236 236 from matplotlib.backends import backend_agg
237 237 from matplotlib.font_manager import FontProperties
238 238 from matplotlib.mathtext import MathTextParser
239 239
240 240 if prop is None:
241 241 prop = FontProperties()
242 242
243 243 parser = MathTextParser('path')
244 244 width, height, depth, _, _ = parser.parse(s, dpi=72, prop=prop)
245 245
246 246 fig = figure.Figure(figsize=(width / 72.0, height / 72.0))
247 247 fig.text(0, depth/height, s, fontproperties=prop)
248 248 backend_agg.FigureCanvasAgg(fig)
249 249 fig.savefig(filename_or_obj, dpi=dpi, format=format)
250 250
251 251 return depth
252 252
@@ -1,198 +1,197 b''
1 1 """Posix-specific implementation of process utilities.
2 2
3 3 This file is only meant to be imported by process.py, not by end-users.
4 4 """
5 5
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (C) 2010-2011 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from __future__ import print_function
17 17
18 18 # Stdlib
19 19 import subprocess as sp
20 20 import sys
21 21
22 22 from IPython.external import pexpect
23 23
24 24 # Our own
25 25 from .autoattr import auto_attr
26 26 from ._process_common import getoutput, arg_split
27 from IPython.utils import text
28 27 from IPython.utils import py3compat
29 28 from IPython.utils.encoding import DEFAULT_ENCODING
30 29
31 30 #-----------------------------------------------------------------------------
32 31 # Function definitions
33 32 #-----------------------------------------------------------------------------
34 33
35 34 def _find_cmd(cmd):
36 35 """Find the full path to a command using which."""
37 36
38 37 path = sp.Popen(['/usr/bin/env', 'which', cmd],
39 38 stdout=sp.PIPE, stderr=sp.PIPE).communicate()[0]
40 39 return py3compat.bytes_to_str(path)
41 40
42 41
43 42 class ProcessHandler(object):
44 43 """Execute subprocesses under the control of pexpect.
45 44 """
46 45 # Timeout in seconds to wait on each reading of the subprocess' output.
47 46 # This should not be set too low to avoid cpu overusage from our side,
48 47 # since we read in a loop whose period is controlled by this timeout.
49 48 read_timeout = 0.05
50 49
51 50 # Timeout to give a process if we receive SIGINT, between sending the
52 51 # SIGINT to the process and forcefully terminating it.
53 52 terminate_timeout = 0.2
54 53
55 54 # File object where stdout and stderr of the subprocess will be written
56 55 logfile = None
57 56
58 57 # Shell to call for subprocesses to execute
59 58 sh = None
60 59
61 60 @auto_attr
62 61 def sh(self):
63 62 sh = pexpect.which('sh')
64 63 if sh is None:
65 64 raise OSError('"sh" shell not found')
66 65 return sh
67 66
68 67 def __init__(self, logfile=None, read_timeout=None, terminate_timeout=None):
69 68 """Arguments are used for pexpect calls."""
70 69 self.read_timeout = (ProcessHandler.read_timeout if read_timeout is
71 70 None else read_timeout)
72 71 self.terminate_timeout = (ProcessHandler.terminate_timeout if
73 72 terminate_timeout is None else
74 73 terminate_timeout)
75 74 self.logfile = sys.stdout if logfile is None else logfile
76 75
77 76 def getoutput(self, cmd):
78 77 """Run a command and return its stdout/stderr as a string.
79 78
80 79 Parameters
81 80 ----------
82 81 cmd : str
83 82 A command to be executed in the system shell.
84 83
85 84 Returns
86 85 -------
87 86 output : str
88 87 A string containing the combination of stdout and stderr from the
89 88 subprocess, in whatever order the subprocess originally wrote to its
90 89 file descriptors (so the order of the information in this string is the
91 90 correct order as would be seen if running the command in a terminal).
92 91 """
93 92 try:
94 93 return pexpect.run(self.sh, args=['-c', cmd]).replace('\r\n', '\n')
95 94 except KeyboardInterrupt:
96 95 print('^C', file=sys.stderr, end='')
97 96
98 97 def getoutput_pexpect(self, cmd):
99 98 """Run a command and return its stdout/stderr as a string.
100 99
101 100 Parameters
102 101 ----------
103 102 cmd : str
104 103 A command to be executed in the system shell.
105 104
106 105 Returns
107 106 -------
108 107 output : str
109 108 A string containing the combination of stdout and stderr from the
110 109 subprocess, in whatever order the subprocess originally wrote to its
111 110 file descriptors (so the order of the information in this string is the
112 111 correct order as would be seen if running the command in a terminal).
113 112 """
114 113 try:
115 114 return pexpect.run(self.sh, args=['-c', cmd]).replace('\r\n', '\n')
116 115 except KeyboardInterrupt:
117 116 print('^C', file=sys.stderr, end='')
118 117
119 118 def system(self, cmd):
120 119 """Execute a command in a subshell.
121 120
122 121 Parameters
123 122 ----------
124 123 cmd : str
125 124 A command to be executed in the system shell.
126 125
127 126 Returns
128 127 -------
129 128 int : child's exitstatus
130 129 """
131 130 # Get likely encoding for the output.
132 131 enc = DEFAULT_ENCODING
133 132
134 133 # Patterns to match on the output, for pexpect. We read input and
135 134 # allow either a short timeout or EOF
136 135 patterns = [pexpect.TIMEOUT, pexpect.EOF]
137 136 # the index of the EOF pattern in the list.
138 137 # even though we know it's 1, this call means we don't have to worry if
139 138 # we change the above list, and forget to change this value:
140 139 EOF_index = patterns.index(pexpect.EOF)
141 140 # The size of the output stored so far in the process output buffer.
142 141 # Since pexpect only appends to this buffer, each time we print we
143 142 # record how far we've printed, so that next time we only print *new*
144 143 # content from the buffer.
145 144 out_size = 0
146 145 try:
147 146 # Since we're not really searching the buffer for text patterns, we
148 147 # can set pexpect's search window to be tiny and it won't matter.
149 148 # We only search for the 'patterns' timeout or EOF, which aren't in
150 149 # the text itself.
151 150 #child = pexpect.spawn(pcmd, searchwindowsize=1)
152 151 if hasattr(pexpect, 'spawnb'):
153 152 child = pexpect.spawnb(self.sh, args=['-c', cmd]) # Pexpect-U
154 153 else:
155 154 child = pexpect.spawn(self.sh, args=['-c', cmd]) # Vanilla Pexpect
156 155 flush = sys.stdout.flush
157 156 while True:
158 157 # res is the index of the pattern that caused the match, so we
159 158 # know whether we've finished (if we matched EOF) or not
160 159 res_idx = child.expect_list(patterns, self.read_timeout)
161 160 print(child.before[out_size:].decode(enc, 'replace'), end='')
162 161 flush()
163 162 if res_idx==EOF_index:
164 163 break
165 164 # Update the pointer to what we've already printed
166 165 out_size = len(child.before)
167 166 except KeyboardInterrupt:
168 167 # We need to send ^C to the process. The ascii code for '^C' is 3
169 168 # (the character is known as ETX for 'End of Text', see
170 169 # curses.ascii.ETX).
171 170 child.sendline(chr(3))
172 171 # Read and print any more output the program might produce on its
173 172 # way out.
174 173 try:
175 174 out_size = len(child.before)
176 175 child.expect_list(patterns, self.terminate_timeout)
177 176 print(child.before[out_size:].decode(enc, 'replace'), end='')
178 177 sys.stdout.flush()
179 178 except KeyboardInterrupt:
180 179 # Impatient users tend to type it multiple times
181 180 pass
182 181 finally:
183 182 # Ensure the subprocess really is terminated
184 183 child.terminate(force=True)
185 184 # add isalive check, to ensure exitstatus is set:
186 185 child.isalive()
187 186 return child.exitstatus
188 187
189 188
190 189 # Make system() with a functional interface for outside use. Note that we use
191 190 # getoutput() from the _common utils, which is built on top of popen(). Using
192 191 # pexpect to get subprocess output produces difficult to parse output, since
193 192 # programs think they are talking to a tty and produce highly formatted output
194 193 # (ls is a good example) that makes them hard.
195 194 system = ProcessHandler().system
196 195
197 196
198 197
@@ -1,189 +1,188 b''
1 1 """Windows-specific implementation of process utilities.
2 2
3 3 This file is only meant to be imported by process.py, not by end-users.
4 4 """
5 5
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (C) 2010-2011 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from __future__ import print_function
17 17
18 18 # stdlib
19 19 import os
20 20 import sys
21 21 import ctypes
22 22 import msvcrt
23 23
24 24 from ctypes import c_int, POINTER
25 25 from ctypes.wintypes import LPCWSTR, HLOCAL
26 26 from subprocess import STDOUT
27 27
28 28 # our own imports
29 29 from ._process_common import read_no_interrupt, process_handler, arg_split as py_arg_split
30 30 from . import py3compat
31 from . import text
32 31 from .encoding import DEFAULT_ENCODING
33 32
34 33 #-----------------------------------------------------------------------------
35 34 # Function definitions
36 35 #-----------------------------------------------------------------------------
37 36
38 37 class AvoidUNCPath(object):
39 38 """A context manager to protect command execution from UNC paths.
40 39
41 40 In the Win32 API, commands can't be invoked with the cwd being a UNC path.
42 41 This context manager temporarily changes directory to the 'C:' drive on
43 42 entering, and restores the original working directory on exit.
44 43
45 44 The context manager returns the starting working directory *if* it made a
46 45 change and None otherwise, so that users can apply the necessary adjustment
47 46 to their system calls in the event of a change.
48 47
49 48 Example
50 49 -------
51 50 ::
52 51 cmd = 'dir'
53 52 with AvoidUNCPath() as path:
54 53 if path is not None:
55 54 cmd = '"pushd %s &&"%s' % (path, cmd)
56 55 os.system(cmd)
57 56 """
58 57 def __enter__(self):
59 58 self.path = os.getcwdu()
60 59 self.is_unc_path = self.path.startswith(r"\\")
61 60 if self.is_unc_path:
62 61 # change to c drive (as cmd.exe cannot handle UNC addresses)
63 62 os.chdir("C:")
64 63 return self.path
65 64 else:
66 65 # We return None to signal that there was no change in the working
67 66 # directory
68 67 return None
69 68
70 69 def __exit__(self, exc_type, exc_value, traceback):
71 70 if self.is_unc_path:
72 71 os.chdir(self.path)
73 72
74 73
75 74 def _find_cmd(cmd):
76 75 """Find the full path to a .bat or .exe using the win32api module."""
77 76 try:
78 77 from win32api import SearchPath
79 78 except ImportError:
80 79 raise ImportError('you need to have pywin32 installed for this to work')
81 80 else:
82 81 PATH = os.environ['PATH']
83 82 extensions = ['.exe', '.com', '.bat', '.py']
84 83 path = None
85 84 for ext in extensions:
86 85 try:
87 86 path = SearchPath(PATH, cmd + ext)[0]
88 87 except:
89 88 pass
90 89 if path is None:
91 90 raise OSError("command %r not found" % cmd)
92 91 else:
93 92 return path
94 93
95 94
96 95 def _system_body(p):
97 96 """Callback for _system."""
98 97 enc = DEFAULT_ENCODING
99 98 for line in read_no_interrupt(p.stdout).splitlines():
100 99 line = line.decode(enc, 'replace')
101 100 print(line, file=sys.stdout)
102 101 for line in read_no_interrupt(p.stderr).splitlines():
103 102 line = line.decode(enc, 'replace')
104 103 print(line, file=sys.stderr)
105 104
106 105 # Wait to finish for returncode
107 106 return p.wait()
108 107
109 108
110 109 def system(cmd):
111 110 """Win32 version of os.system() that works with network shares.
112 111
113 112 Note that this implementation returns None, as meant for use in IPython.
114 113
115 114 Parameters
116 115 ----------
117 116 cmd : str
118 117 A command to be executed in the system shell.
119 118
120 119 Returns
121 120 -------
122 121 None : we explicitly do NOT return the subprocess status code, as this
123 122 utility is meant to be used extensively in IPython, where any return value
124 123 would trigger :func:`sys.displayhook` calls.
125 124 """
126 125 # The controller provides interactivity with both
127 126 # stdin and stdout
128 127 #import _process_win32_controller
129 128 #_process_win32_controller.system(cmd)
130 129
131 130 with AvoidUNCPath() as path:
132 131 if path is not None:
133 132 cmd = '"pushd %s &&"%s' % (path, cmd)
134 133 return process_handler(cmd, _system_body)
135 134
136 135 def getoutput(cmd):
137 136 """Return standard output of executing cmd in a shell.
138 137
139 138 Accepts the same arguments as os.system().
140 139
141 140 Parameters
142 141 ----------
143 142 cmd : str
144 143 A command to be executed in the system shell.
145 144
146 145 Returns
147 146 -------
148 147 stdout : str
149 148 """
150 149
151 150 with AvoidUNCPath() as path:
152 151 if path is not None:
153 152 cmd = '"pushd %s &&"%s' % (path, cmd)
154 153 out = process_handler(cmd, lambda p: p.communicate()[0], STDOUT)
155 154
156 155 if out is None:
157 156 out = b''
158 157 return py3compat.bytes_to_str(out)
159 158
160 159 try:
161 160 CommandLineToArgvW = ctypes.windll.shell32.CommandLineToArgvW
162 161 CommandLineToArgvW.arg_types = [LPCWSTR, POINTER(c_int)]
163 162 CommandLineToArgvW.restype = POINTER(LPCWSTR)
164 163 LocalFree = ctypes.windll.kernel32.LocalFree
165 164 LocalFree.res_type = HLOCAL
166 165 LocalFree.arg_types = [HLOCAL]
167 166
168 167 def arg_split(commandline, posix=False, strict=True):
169 168 """Split a command line's arguments in a shell-like manner.
170 169
171 170 This is a special version for windows that use a ctypes call to CommandLineToArgvW
172 171 to do the argv splitting. The posix paramter is ignored.
173 172
174 173 If strict=False, process_common.arg_split(...strict=False) is used instead.
175 174 """
176 175 #CommandLineToArgvW returns path to executable if called with empty string.
177 176 if commandline.strip() == "":
178 177 return []
179 178 if not strict:
180 179 # not really a cl-arg, fallback on _process_common
181 180 return py_arg_split(commandline, posix=posix, strict=strict)
182 181 argvn = c_int()
183 182 result_pointer = CommandLineToArgvW(py3compat.cast_unicode(commandline.lstrip()), ctypes.byref(argvn))
184 183 result_array_type = LPCWSTR * argvn.value
185 184 result = [arg for arg in result_array_type.from_address(ctypes.addressof(result_pointer.contents))]
186 185 retval = LocalFree(result_pointer)
187 186 return result
188 187 except AttributeError:
189 188 arg_split = py_arg_split
@@ -1,213 +1,211 b''
1 1 """Utilities to manipulate JSON objects.
2 2 """
3 3 #-----------------------------------------------------------------------------
4 4 # Copyright (C) 2010-2011 The IPython Development Team
5 5 #
6 6 # Distributed under the terms of the BSD License. The full license is in
7 7 # the file COPYING.txt, distributed as part of this software.
8 8 #-----------------------------------------------------------------------------
9 9
10 10 #-----------------------------------------------------------------------------
11 11 # Imports
12 12 #-----------------------------------------------------------------------------
13 13 # stdlib
14 14 import math
15 15 import re
16 import sys
17 16 import types
18 17 from datetime import datetime
19 18
20 19 try:
21 20 # base64.encodestring is deprecated in Python 3.x
22 21 from base64 import encodebytes
23 22 except ImportError:
24 23 # Python 2.x
25 24 from base64 import encodestring as encodebytes
26 25
27 26 from IPython.utils import py3compat
28 27 from IPython.utils.encoding import DEFAULT_ENCODING
29 from IPython.utils import text
30 28 next_attr_name = '__next__' if py3compat.PY3 else 'next'
31 29
32 30 #-----------------------------------------------------------------------------
33 31 # Globals and constants
34 32 #-----------------------------------------------------------------------------
35 33
36 34 # timestamp formats
37 35 ISO8601="%Y-%m-%dT%H:%M:%S.%f"
38 36 ISO8601_PAT=re.compile(r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+$")
39 37
40 38 #-----------------------------------------------------------------------------
41 39 # Classes and functions
42 40 #-----------------------------------------------------------------------------
43 41
44 42 def rekey(dikt):
45 43 """Rekey a dict that has been forced to use str keys where there should be
46 44 ints by json."""
47 45 for k in dikt.iterkeys():
48 46 if isinstance(k, basestring):
49 47 ik=fk=None
50 48 try:
51 49 ik = int(k)
52 50 except ValueError:
53 51 try:
54 52 fk = float(k)
55 53 except ValueError:
56 54 continue
57 55 if ik is not None:
58 56 nk = ik
59 57 else:
60 58 nk = fk
61 59 if nk in dikt:
62 60 raise KeyError("already have key %r"%nk)
63 61 dikt[nk] = dikt.pop(k)
64 62 return dikt
65 63
66 64
67 65 def extract_dates(obj):
68 66 """extract ISO8601 dates from unpacked JSON"""
69 67 if isinstance(obj, dict):
70 68 obj = dict(obj) # don't clobber
71 69 for k,v in obj.iteritems():
72 70 obj[k] = extract_dates(v)
73 71 elif isinstance(obj, (list, tuple)):
74 72 obj = [ extract_dates(o) for o in obj ]
75 73 elif isinstance(obj, basestring):
76 74 if ISO8601_PAT.match(obj):
77 75 obj = datetime.strptime(obj, ISO8601)
78 76 return obj
79 77
80 78 def squash_dates(obj):
81 79 """squash datetime objects into ISO8601 strings"""
82 80 if isinstance(obj, dict):
83 81 obj = dict(obj) # don't clobber
84 82 for k,v in obj.iteritems():
85 83 obj[k] = squash_dates(v)
86 84 elif isinstance(obj, (list, tuple)):
87 85 obj = [ squash_dates(o) for o in obj ]
88 86 elif isinstance(obj, datetime):
89 87 obj = obj.strftime(ISO8601)
90 88 return obj
91 89
92 90 def date_default(obj):
93 91 """default function for packing datetime objects in JSON."""
94 92 if isinstance(obj, datetime):
95 93 return obj.strftime(ISO8601)
96 94 else:
97 95 raise TypeError("%r is not JSON serializable"%obj)
98 96
99 97
100 98 # constants for identifying png/jpeg data
101 99 PNG = b'\x89PNG\r\n\x1a\n'
102 100 JPEG = b'\xff\xd8'
103 101
104 102 def encode_images(format_dict):
105 103 """b64-encodes images in a displaypub format dict
106 104
107 105 Perhaps this should be handled in json_clean itself?
108 106
109 107 Parameters
110 108 ----------
111 109
112 110 format_dict : dict
113 111 A dictionary of display data keyed by mime-type
114 112
115 113 Returns
116 114 -------
117 115
118 116 format_dict : dict
119 117 A copy of the same dictionary,
120 118 but binary image data ('image/png' or 'image/jpeg')
121 119 is base64-encoded.
122 120
123 121 """
124 122 encoded = format_dict.copy()
125 123 pngdata = format_dict.get('image/png')
126 124 if isinstance(pngdata, bytes) and pngdata[:8] == PNG:
127 125 encoded['image/png'] = encodebytes(pngdata).decode('ascii')
128 126 jpegdata = format_dict.get('image/jpeg')
129 127 if isinstance(jpegdata, bytes) and jpegdata[:2] == JPEG:
130 128 encoded['image/jpeg'] = encodebytes(jpegdata).decode('ascii')
131 129 return encoded
132 130
133 131
134 132 def json_clean(obj):
135 133 """Clean an object to ensure it's safe to encode in JSON.
136 134
137 135 Atomic, immutable objects are returned unmodified. Sets and tuples are
138 136 converted to lists, lists are copied and dicts are also copied.
139 137
140 138 Note: dicts whose keys could cause collisions upon encoding (such as a dict
141 139 with both the number 1 and the string '1' as keys) will cause a ValueError
142 140 to be raised.
143 141
144 142 Parameters
145 143 ----------
146 144 obj : any python object
147 145
148 146 Returns
149 147 -------
150 148 out : object
151 149
152 150 A version of the input which will not cause an encoding error when
153 151 encoded as JSON. Note that this function does not *encode* its inputs,
154 152 it simply sanitizes it so that there will be no encoding errors later.
155 153
156 154 Examples
157 155 --------
158 156 >>> json_clean(4)
159 157 4
160 158 >>> json_clean(range(10))
161 159 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
162 160 >>> sorted(json_clean(dict(x=1, y=2)).items())
163 161 [('x', 1), ('y', 2)]
164 162 >>> sorted(json_clean(dict(x=1, y=2, z=[1,2,3])).items())
165 163 [('x', 1), ('y', 2), ('z', [1, 2, 3])]
166 164 >>> json_clean(True)
167 165 True
168 166 """
169 167 # types that are 'atomic' and ok in json as-is. bool doesn't need to be
170 168 # listed explicitly because bools pass as int instances
171 169 atomic_ok = (unicode, int, types.NoneType)
172 170
173 171 # containers that we need to convert into lists
174 172 container_to_list = (tuple, set, types.GeneratorType)
175 173
176 174 if isinstance(obj, float):
177 175 # cast out-of-range floats to their reprs
178 176 if math.isnan(obj) or math.isinf(obj):
179 177 return repr(obj)
180 178 return obj
181 179
182 180 if isinstance(obj, atomic_ok):
183 181 return obj
184 182
185 183 if isinstance(obj, bytes):
186 184 return obj.decode(DEFAULT_ENCODING, 'replace')
187 185
188 186 if isinstance(obj, container_to_list) or (
189 187 hasattr(obj, '__iter__') and hasattr(obj, next_attr_name)):
190 188 obj = list(obj)
191 189
192 190 if isinstance(obj, list):
193 191 return [json_clean(x) for x in obj]
194 192
195 193 if isinstance(obj, dict):
196 194 # First, validate that the dict won't lose data in conversion due to
197 195 # key collisions after stringification. This can happen with keys like
198 196 # True and 'true' or 1 and '1', which collide in JSON.
199 197 nkeys = len(obj)
200 198 nkeys_collapsed = len(set(map(str, obj)))
201 199 if nkeys != nkeys_collapsed:
202 200 raise ValueError('dict can not be safely converted to JSON: '
203 201 'key collision would lead to dropped values')
204 202 # If all OK, proceed by making the new dict that will be json-safe
205 203 out = {}
206 204 for k,v in obj.iteritems():
207 205 out[str(k)] = json_clean(v)
208 206 return out
209 207
210 208 # If we get here, we don't know how to handle the object, so we just get
211 209 # its repr and return that. This will catch lambdas, open sockets, class
212 210 # objects, and any other complicated contraption that json can't encode
213 211 return repr(obj)
@@ -1,325 +1,324 b''
1 1 # encoding: utf-8
2 2
3 3 """Pickle related utilities. Perhaps this should be called 'can'."""
4 4
5 5 __docformat__ = "restructuredtext en"
6 6
7 7 #-------------------------------------------------------------------------------
8 8 # Copyright (C) 2008-2011 The IPython Development Team
9 9 #
10 10 # Distributed under the terms of the BSD License. The full license is in
11 11 # the file COPYING, distributed as part of this software.
12 12 #-------------------------------------------------------------------------------
13 13
14 14 #-------------------------------------------------------------------------------
15 15 # Imports
16 16 #-------------------------------------------------------------------------------
17 17
18 18 import copy
19 19 import logging
20 20 import sys
21 21 from types import FunctionType
22 22
23 23 try:
24 24 import cPickle as pickle
25 25 except ImportError:
26 26 import pickle
27 27
28 28 try:
29 29 import numpy
30 30 except:
31 31 numpy = None
32 32
33 import codeutil
34 33 import py3compat
35 34 from importstring import import_item
36 35
37 36 from IPython.config import Application
38 37
39 38 if py3compat.PY3:
40 39 buffer = memoryview
41 40 class_type = type
42 41 else:
43 42 from types import ClassType
44 43 class_type = (type, ClassType)
45 44
46 45 #-------------------------------------------------------------------------------
47 46 # Classes
48 47 #-------------------------------------------------------------------------------
49 48
50 49
51 50 class CannedObject(object):
52 51 def __init__(self, obj, keys=[]):
53 52 self.keys = keys
54 53 self.obj = copy.copy(obj)
55 54 for key in keys:
56 55 setattr(self.obj, key, can(getattr(obj, key)))
57 56
58 57 self.buffers = []
59 58
60 59 def get_object(self, g=None):
61 60 if g is None:
62 61 g = {}
63 62 for key in self.keys:
64 63 setattr(self.obj, key, uncan(getattr(self.obj, key), g))
65 64 return self.obj
66 65
67 66
68 67 class Reference(CannedObject):
69 68 """object for wrapping a remote reference by name."""
70 69 def __init__(self, name):
71 70 if not isinstance(name, basestring):
72 71 raise TypeError("illegal name: %r"%name)
73 72 self.name = name
74 73 self.buffers = []
75 74
76 75 def __repr__(self):
77 76 return "<Reference: %r>"%self.name
78 77
79 78 def get_object(self, g=None):
80 79 if g is None:
81 80 g = {}
82 81
83 82 return eval(self.name, g)
84 83
85 84
86 85 class CannedFunction(CannedObject):
87 86
88 87 def __init__(self, f):
89 88 self._check_type(f)
90 89 self.code = f.func_code
91 90 if f.func_defaults:
92 91 self.defaults = [ can(fd) for fd in f.func_defaults ]
93 92 else:
94 93 self.defaults = None
95 94 self.module = f.__module__ or '__main__'
96 95 self.__name__ = f.__name__
97 96 self.buffers = []
98 97
99 98 def _check_type(self, obj):
100 99 assert isinstance(obj, FunctionType), "Not a function type"
101 100
102 101 def get_object(self, g=None):
103 102 # try to load function back into its module:
104 103 if not self.module.startswith('__'):
105 104 __import__(self.module)
106 105 g = sys.modules[self.module].__dict__
107 106
108 107 if g is None:
109 108 g = {}
110 109 if self.defaults:
111 110 defaults = tuple(uncan(cfd, g) for cfd in self.defaults)
112 111 else:
113 112 defaults = None
114 113 newFunc = FunctionType(self.code, g, self.__name__, defaults)
115 114 return newFunc
116 115
117 116 class CannedClass(CannedObject):
118 117
119 118 def __init__(self, cls):
120 119 self._check_type(cls)
121 120 self.name = cls.__name__
122 121 self.old_style = not isinstance(cls, type)
123 122 self._canned_dict = {}
124 123 for k,v in cls.__dict__.items():
125 124 if k not in ('__weakref__', '__dict__'):
126 125 self._canned_dict[k] = can(v)
127 126 if self.old_style:
128 127 mro = []
129 128 else:
130 129 mro = cls.mro()
131 130
132 131 self.parents = [ can(c) for c in mro[1:] ]
133 132 self.buffers = []
134 133
135 134 def _check_type(self, obj):
136 135 assert isinstance(obj, class_type), "Not a class type"
137 136
138 137 def get_object(self, g=None):
139 138 parents = tuple(uncan(p, g) for p in self.parents)
140 139 return type(self.name, parents, uncan_dict(self._canned_dict, g=g))
141 140
142 141 class CannedArray(CannedObject):
143 142 def __init__(self, obj):
144 143 self.shape = obj.shape
145 144 self.dtype = obj.dtype.descr if obj.dtype.fields else obj.dtype.str
146 145 if sum(obj.shape) == 0:
147 146 # just pickle it
148 147 self.buffers = [pickle.dumps(obj, -1)]
149 148 else:
150 149 # ensure contiguous
151 150 obj = numpy.ascontiguousarray(obj, dtype=None)
152 151 self.buffers = [buffer(obj)]
153 152
154 153 def get_object(self, g=None):
155 154 data = self.buffers[0]
156 155 if sum(self.shape) == 0:
157 156 # no shape, we just pickled it
158 157 return pickle.loads(data)
159 158 else:
160 159 return numpy.frombuffer(data, dtype=self.dtype).reshape(self.shape)
161 160
162 161
163 162 class CannedBytes(CannedObject):
164 163 wrap = bytes
165 164 def __init__(self, obj):
166 165 self.buffers = [obj]
167 166
168 167 def get_object(self, g=None):
169 168 data = self.buffers[0]
170 169 return self.wrap(data)
171 170
172 171 def CannedBuffer(CannedBytes):
173 172 wrap = buffer
174 173
175 174 #-------------------------------------------------------------------------------
176 175 # Functions
177 176 #-------------------------------------------------------------------------------
178 177
179 178 def _logger():
180 179 """get the logger for the current Application
181 180
182 181 the root logger will be used if no Application is running
183 182 """
184 183 if Application.initialized():
185 184 logger = Application.instance().log
186 185 else:
187 186 logger = logging.getLogger()
188 187 if not logger.handlers:
189 188 logging.basicConfig()
190 189
191 190 return logger
192 191
193 192 def _import_mapping(mapping, original=None):
194 193 """import any string-keys in a type mapping
195 194
196 195 """
197 196 log = _logger()
198 197 log.debug("Importing canning map")
199 198 for key,value in mapping.items():
200 199 if isinstance(key, basestring):
201 200 try:
202 201 cls = import_item(key)
203 202 except Exception:
204 203 if original and key not in original:
205 204 # only message on user-added classes
206 205 log.error("cannning class not importable: %r", key, exc_info=True)
207 206 mapping.pop(key)
208 207 else:
209 208 mapping[cls] = mapping.pop(key)
210 209
211 210 def istype(obj, check):
212 211 """like isinstance(obj, check), but strict
213 212
214 213 This won't catch subclasses.
215 214 """
216 215 if isinstance(check, tuple):
217 216 for cls in check:
218 217 if type(obj) is cls:
219 218 return True
220 219 return False
221 220 else:
222 221 return type(obj) is check
223 222
224 223 def can(obj):
225 224 """prepare an object for pickling"""
226 225
227 226 import_needed = False
228 227
229 228 for cls,canner in can_map.iteritems():
230 229 if isinstance(cls, basestring):
231 230 import_needed = True
232 231 break
233 232 elif istype(obj, cls):
234 233 return canner(obj)
235 234
236 235 if import_needed:
237 236 # perform can_map imports, then try again
238 237 # this will usually only happen once
239 238 _import_mapping(can_map, _original_can_map)
240 239 return can(obj)
241 240
242 241 return obj
243 242
244 243 def can_class(obj):
245 244 if isinstance(obj, class_type) and obj.__module__ == '__main__':
246 245 return CannedClass(obj)
247 246 else:
248 247 return obj
249 248
250 249 def can_dict(obj):
251 250 """can the *values* of a dict"""
252 251 if isinstance(obj, dict):
253 252 newobj = {}
254 253 for k, v in obj.iteritems():
255 254 newobj[k] = can(v)
256 255 return newobj
257 256 else:
258 257 return obj
259 258
260 259 def can_sequence(obj):
261 260 """can the elements of a sequence"""
262 261 if isinstance(obj, (list, tuple)):
263 262 t = type(obj)
264 263 return t([can(i) for i in obj])
265 264 else:
266 265 return obj
267 266
268 267 def uncan(obj, g=None):
269 268 """invert canning"""
270 269
271 270 import_needed = False
272 271 for cls,uncanner in uncan_map.iteritems():
273 272 if isinstance(cls, basestring):
274 273 import_needed = True
275 274 break
276 275 elif isinstance(obj, cls):
277 276 return uncanner(obj, g)
278 277
279 278 if import_needed:
280 279 # perform uncan_map imports, then try again
281 280 # this will usually only happen once
282 281 _import_mapping(uncan_map, _original_uncan_map)
283 282 return uncan(obj, g)
284 283
285 284 return obj
286 285
287 286 def uncan_dict(obj, g=None):
288 287 if isinstance(obj, dict):
289 288 newobj = {}
290 289 for k, v in obj.iteritems():
291 290 newobj[k] = uncan(v,g)
292 291 return newobj
293 292 else:
294 293 return obj
295 294
296 295 def uncan_sequence(obj, g=None):
297 296 if isinstance(obj, (list, tuple)):
298 297 t = type(obj)
299 298 return t([uncan(i,g) for i in obj])
300 299 else:
301 300 return obj
302 301
303 302
304 303 #-------------------------------------------------------------------------------
305 304 # API dictionaries
306 305 #-------------------------------------------------------------------------------
307 306
308 307 # These dicts can be extended for custom serialization of new objects
309 308
310 309 can_map = {
311 310 'IPython.parallel.dependent' : lambda obj: CannedObject(obj, keys=('f','df')),
312 311 'numpy.ndarray' : CannedArray,
313 312 FunctionType : CannedFunction,
314 313 bytes : CannedBytes,
315 314 buffer : CannedBuffer,
316 315 class_type : can_class,
317 316 }
318 317
319 318 uncan_map = {
320 319 CannedObject : lambda obj, g: obj.get_object(g),
321 320 }
322 321
323 322 # for use in _import_mapping:
324 323 _original_can_map = can_map.copy()
325 324 _original_uncan_map = uncan_map.copy()
@@ -1,126 +1,125 b''
1 1 # encoding: utf-8
2 2 """
3 3 Utilities for working with external processes.
4 4 """
5 5
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (C) 2008-2011 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16 from __future__ import print_function
17 17
18 18 # Stdlib
19 19 import os
20 20 import sys
21 21 import shlex
22 22
23 23 # Our own
24 24 if sys.platform == 'win32':
25 25 from ._process_win32 import _find_cmd, system, getoutput, AvoidUNCPath, arg_split
26 26 else:
27 27 from ._process_posix import _find_cmd, system, getoutput, arg_split
28 28
29 29
30 30 from ._process_common import getoutputerror
31 from IPython.utils import py3compat
32 31
33 32 #-----------------------------------------------------------------------------
34 33 # Code
35 34 #-----------------------------------------------------------------------------
36 35
37 36
38 37 class FindCmdError(Exception):
39 38 pass
40 39
41 40
42 41 def find_cmd(cmd):
43 42 """Find absolute path to executable cmd in a cross platform manner.
44 43
45 44 This function tries to determine the full path to a command line program
46 45 using `which` on Unix/Linux/OS X and `win32api` on Windows. Most of the
47 46 time it will use the version that is first on the users `PATH`. If
48 47 cmd is `python` return `sys.executable`.
49 48
50 49 Warning, don't use this to find IPython command line programs as there
51 50 is a risk you will find the wrong one. Instead find those using the
52 51 following code and looking for the application itself::
53 52
54 53 from IPython.utils.path import get_ipython_module_path
55 54 from IPython.utils.process import pycmd2argv
56 55 argv = pycmd2argv(get_ipython_module_path('IPython.frontend.terminal.ipapp'))
57 56
58 57 Parameters
59 58 ----------
60 59 cmd : str
61 60 The command line program to look for.
62 61 """
63 62 if cmd == 'python':
64 63 return os.path.abspath(sys.executable)
65 64 try:
66 65 path = _find_cmd(cmd).rstrip()
67 66 except OSError:
68 67 raise FindCmdError('command could not be found: %s' % cmd)
69 68 # which returns empty if not found
70 69 if path == '':
71 70 raise FindCmdError('command could not be found: %s' % cmd)
72 71 return os.path.abspath(path)
73 72
74 73
75 74 def is_cmd_found(cmd):
76 75 """Check whether executable `cmd` exists or not and return a bool."""
77 76 try:
78 77 find_cmd(cmd)
79 78 return True
80 79 except FindCmdError:
81 80 return False
82 81
83 82
84 83 def pycmd2argv(cmd):
85 84 r"""Take the path of a python command and return a list (argv-style).
86 85
87 86 This only works on Python based command line programs and will find the
88 87 location of the ``python`` executable using ``sys.executable`` to make
89 88 sure the right version is used.
90 89
91 90 For a given path ``cmd``, this returns [cmd] if cmd's extension is .exe,
92 91 .com or .bat, and [, cmd] otherwise.
93 92
94 93 Parameters
95 94 ----------
96 95 cmd : string
97 96 The path of the command.
98 97
99 98 Returns
100 99 -------
101 100 argv-style list.
102 101 """
103 102 ext = os.path.splitext(cmd)[1]
104 103 if ext in ['.exe', '.com', '.bat']:
105 104 return [cmd]
106 105 else:
107 106 return [sys.executable, cmd]
108 107
109 108
110 109 def abbrev_cwd():
111 110 """ Return abbreviated version of cwd, e.g. d:mydir """
112 111 cwd = os.getcwdu().replace('\\','/')
113 112 drivepart = ''
114 113 tail = cwd
115 114 if sys.platform == 'win32':
116 115 if len(cwd) < 4:
117 116 return cwd
118 117 drivepart,tail = os.path.splitdrive(cwd)
119 118
120 119
121 120 parts = tail.split('/')
122 121 if len(parts) > 2:
123 122 tail = '/'.join(parts[-2:])
124 123
125 124 return (drivepart + (
126 125 cwd == '/' and '/' or tail))
@@ -1,124 +1,119 b''
1 1 # -*- coding: utf-8 -*-
2 2 """ Imports and provides the 'correct' version of readline for the platform.
3 3
4 4 Readline is used throughout IPython as::
5 5
6 6 import IPython.utils.rlineimpl as readline
7 7
8 8 In addition to normal readline stuff, this module provides have_readline
9 9 boolean and _outputfile variable used in IPython.utils.
10 10 """
11 11
12 import os
13 import re
14 12 import sys
15 import time
16 13 import warnings
17 14
18 from subprocess import Popen, PIPE
19
20 15 if sys.platform == 'darwin':
21 16 # dirty trick, to skip the system readline, because pip-installed readline
22 17 # will never be found on OSX, since lib-dynload always comes ahead of site-packages
23 18 from distutils import sysconfig
24 19 lib_dynload = sysconfig.get_config_var('DESTSHARED')
25 20 del sysconfig
26 21 try:
27 22 dynload_idx = sys.path.index(lib_dynload)
28 23 except ValueError:
29 24 dynload_idx = None
30 25 else:
31 26 sys.path.pop(dynload_idx)
32 27 try:
33 28 from readline import *
34 29 import readline as _rl
35 30 have_readline = True
36 31 except ImportError:
37 32 try:
38 33 from pyreadline import *
39 34 import pyreadline as _rl
40 35 have_readline = True
41 36 except ImportError:
42 37 have_readline = False
43 38
44 39 if sys.platform == 'darwin':
45 40 # dirty trick, part II:
46 41 if dynload_idx is not None:
47 42 # restore path
48 43 sys.path.insert(dynload_idx, lib_dynload)
49 44 if not have_readline:
50 45 # *only* have system readline, try import again
51 46 try:
52 47 from readline import *
53 48 import readline as _rl
54 49 have_readline = True
55 50 except ImportError:
56 51 have_readline = False
57 52 else:
58 53 # if we want to warn about EPD / Fink having bad readline
59 54 # we would do it here
60 55 pass
61 56 # cleanup dirty trick vars
62 57 del dynload_idx, lib_dynload
63 58
64 59 if have_readline and hasattr(_rl, 'rlmain'):
65 60 # patch add_history to allow for strings in pyreadline <= 1.5:
66 61 # fix copied from pyreadline 1.6
67 62 import pyreadline
68 63 if pyreadline.release.version <= '1.5':
69 64 def add_history(line):
70 65 """add a line to the history buffer."""
71 66 from pyreadline import lineobj
72 67 if not isinstance(line, lineobj.TextLine):
73 68 line = lineobj.TextLine(line)
74 69 return _rl.add_history(line)
75 70
76 71 if (sys.platform == 'win32' or sys.platform == 'cli') and have_readline:
77 72 try:
78 73 _outputfile=_rl.GetOutputFile()
79 74 except AttributeError:
80 75 warnings.warn("Failed GetOutputFile")
81 76 have_readline = False
82 77
83 78 # Test to see if libedit is being used instead of GNU readline.
84 79 # Thanks to Boyd Waters for the original patch.
85 80 uses_libedit = False
86 81
87 82 if have_readline:
88 83 # Official Python docs state that 'libedit' is in the docstring for libedit readline:
89 84 uses_libedit = _rl.__doc__ and 'libedit' in _rl.__doc__
90 85 # Note that many non-System Pythons also do not use proper readline,
91 86 # but do not report libedit at all, nor are they linked dynamically against libedit.
92 87 # known culprits of this include: EPD, Fink
93 88 # There is not much we can do to detect this, until we find a specific failure
94 89 # case, rather than relying on the readline module to self-identify as broken.
95 90
96 91 if uses_libedit and sys.platform == 'darwin':
97 92 _rl.parse_and_bind("bind ^I rl_complete")
98 93 warnings.warn('\n'.join(['', "*"*78,
99 94 "libedit detected - readline will not be well behaved, including but not limited to:",
100 95 " * crashes on tab completion",
101 96 " * incorrect history navigation",
102 97 " * corrupting long-lines",
103 98 " * failure to wrap or indent lines properly",
104 99 "It is highly recommended that you install readline, which is easy_installable:",
105 100 " easy_install readline",
106 101 "Note that `pip install readline` generally DOES NOT WORK, because",
107 102 "it installs to site-packages, which come *after* lib-dynload in sys.path,",
108 103 "where readline is located. It must be `easy_install readline`, or to a custom",
109 104 "location on your PYTHONPATH (even --user comes after lib-dyload).",
110 105 "*"*78]),
111 106 RuntimeWarning)
112 107
113 108 # the clear_history() function was only introduced in Python 2.4 and is
114 109 # actually optional in the readline API, so we must explicitly check for its
115 110 # existence. Some known platforms actually don't have it. This thread:
116 111 # http://mail.python.org/pipermail/python-dev/2003-August/037845.html
117 112 # has the original discussion.
118 113
119 114 if have_readline:
120 115 try:
121 116 _rl.clear_history
122 117 except AttributeError:
123 118 def clear_history(): pass
124 119 _rl.clear_history = clear_history
@@ -1,168 +1,166 b''
1 1 # encoding: utf-8
2 2 """
3 3 Utilities for getting information about IPython and the system it's running in.
4 4 """
5 5
6 6 #-----------------------------------------------------------------------------
7 7 # Copyright (C) 2008-2011 The IPython Development Team
8 8 #
9 9 # Distributed under the terms of the BSD License. The full license is in
10 10 # the file COPYING, distributed as part of this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16
17 17 import os
18 18 import platform
19 19 import pprint
20 20 import sys
21 21 import subprocess
22 22
23 from ConfigParser import ConfigParser
24
25 23 from IPython.core import release
26 24 from IPython.utils import py3compat, _sysinfo, encoding
27 25
28 26 #-----------------------------------------------------------------------------
29 27 # Code
30 28 #-----------------------------------------------------------------------------
31 29
32 30 def pkg_commit_hash(pkg_path):
33 31 """Get short form of commit hash given directory `pkg_path`
34 32
35 33 We get the commit hash from (in order of preference):
36 34
37 35 * IPython.utils._sysinfo.commit
38 36 * git output, if we are in a git repository
39 37
40 38 If these fail, we return a not-found placeholder tuple
41 39
42 40 Parameters
43 41 ----------
44 42 pkg_path : str
45 43 directory containing package
46 44 only used for getting commit from active repo
47 45
48 46 Returns
49 47 -------
50 48 hash_from : str
51 49 Where we got the hash from - description
52 50 hash_str : str
53 51 short form of hash
54 52 """
55 53 # Try and get commit from written commit text file
56 54 if _sysinfo.commit:
57 55 return "installation", _sysinfo.commit
58 56
59 57 # maybe we are in a repository
60 58 proc = subprocess.Popen('git rev-parse --short HEAD',
61 59 stdout=subprocess.PIPE,
62 60 stderr=subprocess.PIPE,
63 61 cwd=pkg_path, shell=True)
64 62 repo_commit, _ = proc.communicate()
65 63 if repo_commit:
66 64 return 'repository', repo_commit.strip()
67 65 return '(none found)', '<not found>'
68 66
69 67
70 68 def pkg_info(pkg_path):
71 69 """Return dict describing the context of this package
72 70
73 71 Parameters
74 72 ----------
75 73 pkg_path : str
76 74 path containing __init__.py for package
77 75
78 76 Returns
79 77 -------
80 78 context : dict
81 79 with named parameters of interest
82 80 """
83 81 src, hsh = pkg_commit_hash(pkg_path)
84 82 return dict(
85 83 ipython_version=release.version,
86 84 ipython_path=pkg_path,
87 85 commit_source=src,
88 86 commit_hash=hsh,
89 87 sys_version=sys.version,
90 88 sys_executable=sys.executable,
91 89 sys_platform=sys.platform,
92 90 platform=platform.platform(),
93 91 os_name=os.name,
94 92 default_encoding=encoding.DEFAULT_ENCODING,
95 93 )
96 94
97 95
98 96 @py3compat.doctest_refactor_print
99 97 def sys_info():
100 98 """Return useful information about IPython and the system, as a string.
101 99
102 100 Example
103 101 -------
104 102 In [2]: print sys_info()
105 103 {'commit_hash': '144fdae', # random
106 104 'commit_source': 'repository',
107 105 'ipython_path': '/home/fperez/usr/lib/python2.6/site-packages/IPython',
108 106 'ipython_version': '0.11.dev',
109 107 'os_name': 'posix',
110 108 'platform': 'Linux-2.6.35-22-generic-i686-with-Ubuntu-10.10-maverick',
111 109 'sys_executable': '/usr/bin/python',
112 110 'sys_platform': 'linux2',
113 111 'sys_version': '2.6.6 (r266:84292, Sep 15 2010, 15:52:39) \\n[GCC 4.4.5]'}
114 112 """
115 113 p = os.path
116 114 path = p.dirname(p.abspath(p.join(__file__, '..')))
117 115 return pprint.pformat(pkg_info(path))
118 116
119 117
120 118 def _num_cpus_unix():
121 119 """Return the number of active CPUs on a Unix system."""
122 120 return os.sysconf("SC_NPROCESSORS_ONLN")
123 121
124 122
125 123 def _num_cpus_darwin():
126 124 """Return the number of active CPUs on a Darwin system."""
127 125 p = subprocess.Popen(['sysctl','-n','hw.ncpu'],stdout=subprocess.PIPE)
128 126 return p.stdout.read()
129 127
130 128
131 129 def _num_cpus_windows():
132 130 """Return the number of active CPUs on a Windows system."""
133 131 return os.environ.get("NUMBER_OF_PROCESSORS")
134 132
135 133
136 134 def num_cpus():
137 135 """Return the effective number of CPUs in the system as an integer.
138 136
139 137 This cross-platform function makes an attempt at finding the total number of
140 138 available CPUs in the system, as returned by various underlying system and
141 139 python calls.
142 140
143 141 If it can't find a sensible answer, it returns 1 (though an error *may* make
144 142 it return a large positive number that's actually incorrect).
145 143 """
146 144
147 145 # Many thanks to the Parallel Python project (http://www.parallelpython.com)
148 146 # for the names of the keys we needed to look up for this function. This
149 147 # code was inspired by their equivalent function.
150 148
151 149 ncpufuncs = {'Linux':_num_cpus_unix,
152 150 'Darwin':_num_cpus_darwin,
153 151 'Windows':_num_cpus_windows,
154 152 # On Vista, python < 2.5.2 has a bug and returns 'Microsoft'
155 153 # See http://bugs.python.org/issue1082 for details.
156 154 'Microsoft':_num_cpus_windows,
157 155 }
158 156
159 157 ncpufunc = ncpufuncs.get(platform.system(),
160 158 # default to unix version (Solaris, AIX, etc)
161 159 _num_cpus_unix)
162 160
163 161 try:
164 162 ncpus = max(1,int(ncpufunc()))
165 163 except:
166 164 ncpus = 1
167 165 return ncpus
168 166
General Comments 0
You need to be logged in to leave comments. Login now