##// END OF EJS Templates
pythonw in py3k sets std{in,out,err} to None...
Brandon Parsons -
Show More
@@ -1,138 +1,139 b''
1 1 # encoding: utf-8
2 2 """
3 3 Simple utility for splitting user input. This is used by both inputsplitter and
4 4 prefilter.
5 5
6 6 Authors:
7 7
8 8 * Brian Granger
9 9 * Fernando Perez
10 10 """
11 11
12 12 #-----------------------------------------------------------------------------
13 13 # Copyright (C) 2008-2011 The IPython Development Team
14 14 #
15 15 # Distributed under the terms of the BSD License. The full license is in
16 16 # the file COPYING, distributed as part of this software.
17 17 #-----------------------------------------------------------------------------
18 18
19 19 #-----------------------------------------------------------------------------
20 20 # Imports
21 21 #-----------------------------------------------------------------------------
22 22
23 23 import re
24 24 import sys
25 25
26 26 from IPython.utils import py3compat
27 27
28 28 #-----------------------------------------------------------------------------
29 29 # Main function
30 30 #-----------------------------------------------------------------------------
31 31
32 32 # RegExp for splitting line contents into pre-char//first word-method//rest.
33 33 # For clarity, each group in on one line.
34 34
35 35 # WARNING: update the regexp if the escapes in interactiveshell are changed, as
36 36 # they are hardwired in.
37 37
38 38 # Although it's not solely driven by the regex, note that:
39 39 # ,;/% only trigger if they are the first character on the line
40 40 # ! and !! trigger if they are first char(s) *or* follow an indent
41 41 # ? triggers as first or last char.
42 42
43 43 line_split = re.compile("""
44 44 ^(\s*) # any leading space
45 45 ([,;/%]|!!?|\?\??)? # escape character or characters
46 46 \s*(%?[\w\.\*]*) # function/method, possibly with leading %
47 47 # to correctly treat things like '?%magic'
48 48 (.*?$|$) # rest of line
49 49 """, re.VERBOSE)
50 50
51 51 def split_user_input(line, pattern=None):
52 52 """Split user input into initial whitespace, escape character, function part
53 53 and the rest.
54 54 """
55 55 # We need to ensure that the rest of this routine deals only with unicode
56 line = py3compat.cast_unicode(line, sys.stdin.encoding or 'utf-8')
56 encoding = py3compat.get_stream_enc(sys.stdin, 'utf-8')
57 line = py3compat.cast_unicode(line, encoding)
57 58
58 59 if pattern is None:
59 60 pattern = line_split
60 61 match = pattern.match(line)
61 62 if not match:
62 63 # print "match failed for line '%s'" % line
63 64 try:
64 65 ifun, the_rest = line.split(None,1)
65 66 except ValueError:
66 67 # print "split failed for line '%s'" % line
67 68 ifun, the_rest = line, u''
68 69 pre = re.match('^(\s*)(.*)',line).groups()[0]
69 70 esc = ""
70 71 else:
71 72 pre, esc, ifun, the_rest = match.groups()
72 73
73 74 #print 'line:<%s>' % line # dbg
74 75 #print 'pre <%s> ifun <%s> rest <%s>' % (pre,ifun.strip(),the_rest) # dbg
75 76 return pre, esc or '', ifun.strip(), the_rest.lstrip()
76 77
77 78 class LineInfo(object):
78 79 """A single line of input and associated info.
79 80
80 81 Includes the following as properties:
81 82
82 83 line
83 84 The original, raw line
84 85
85 86 continue_prompt
86 87 Is this line a continuation in a sequence of multiline input?
87 88
88 89 pre
89 90 Any leading whitespace.
90 91
91 92 esc
92 93 The escape character(s) in pre or the empty string if there isn't one.
93 94 Note that '!!' and '??' are possible values for esc. Otherwise it will
94 95 always be a single character.
95 96
96 97 ifun
97 98 The 'function part', which is basically the maximal initial sequence
98 99 of valid python identifiers and the '.' character. This is what is
99 100 checked for alias and magic transformations, used for auto-calling,
100 101 etc. In contrast to Python identifiers, it may start with "%" and contain
101 102 "*".
102 103
103 104 the_rest
104 105 Everything else on the line.
105 106 """
106 107 def __init__(self, line, continue_prompt=False):
107 108 self.line = line
108 109 self.continue_prompt = continue_prompt
109 110 self.pre, self.esc, self.ifun, self.the_rest = split_user_input(line)
110 111
111 112 self.pre_char = self.pre.strip()
112 113 if self.pre_char:
113 114 self.pre_whitespace = '' # No whitespace allowd before esc chars
114 115 else:
115 116 self.pre_whitespace = self.pre
116 117
117 118 self._oinfo = None
118 119
119 120 def ofind(self, ip):
120 121 """Do a full, attribute-walking lookup of the ifun in the various
121 122 namespaces for the given IPython InteractiveShell instance.
122 123
123 124 Return a dict with keys: found,obj,ospace,ismagic
124 125
125 126 Note: can cause state changes because of calling getattr, but should
126 127 only be run if autocall is on and if the line hasn't matched any
127 128 other, less dangerous handlers.
128 129
129 130 Does cache the results of the call, so can be called multiple times
130 131 without worrying about *further* damaging state.
131 132 """
132 133 if not self._oinfo:
133 134 # ip.shell._ofind is actually on the Magic class!
134 135 self._oinfo = ip.shell._ofind(self.ifun)
135 136 return self._oinfo
136 137
137 138 def __str__(self):
138 139 return "LineInfo [%s|%s|%s|%s]" %(self.pre, self.esc, self.ifun, self.the_rest)
@@ -1,668 +1,668 b''
1 1 # -*- coding: utf-8 -*-
2 2 """Subclass of InteractiveShell for terminal based frontends."""
3 3
4 4 #-----------------------------------------------------------------------------
5 5 # Copyright (C) 2001 Janko Hauser <jhauser@zscout.de>
6 6 # Copyright (C) 2001-2007 Fernando Perez. <fperez@colorado.edu>
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 __builtin__
18 18 import bdb
19 19 import os
20 20 import re
21 21 import sys
22 22 import textwrap
23 23
24 24 try:
25 25 from contextlib import nested
26 26 except:
27 27 from IPython.utils.nested_context import nested
28 28
29 29 from IPython.core.error import TryNext, UsageError
30 30 from IPython.core.usage import interactive_usage, default_banner
31 31 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
32 32 from IPython.core.pylabtools import pylab_activate
33 33 from IPython.testing.skipdoctest import skip_doctest
34 34 from IPython.utils import py3compat
35 35 from IPython.utils.terminal import toggle_set_term_title, set_term_title
36 36 from IPython.utils.process import abbrev_cwd
37 37 from IPython.utils.warn import warn, error
38 38 from IPython.utils.text import num_ini_spaces, SList
39 39 from IPython.utils.traitlets import Integer, CBool, Unicode
40 40
41 41 #-----------------------------------------------------------------------------
42 42 # Utilities
43 43 #-----------------------------------------------------------------------------
44 44
45 45 def get_default_editor():
46 46 try:
47 47 ed = os.environ['EDITOR']
48 48 except KeyError:
49 49 if os.name == 'posix':
50 50 ed = 'vi' # the only one guaranteed to be there!
51 51 else:
52 52 ed = 'notepad' # same in Windows!
53 53 return ed
54 54
55 55
56 56 def get_pasted_lines(sentinel, l_input=py3compat.input):
57 57 """ Yield pasted lines until the user enters the given sentinel value.
58 58 """
59 59 print "Pasting code; enter '%s' alone on the line to stop or use Ctrl-D." \
60 60 % sentinel
61 61 while True:
62 62 try:
63 63 l = l_input(':')
64 64 if l == sentinel:
65 65 return
66 66 else:
67 67 yield l
68 68 except EOFError:
69 69 print '<EOF>'
70 70 return
71 71
72 72
73 73 def strip_email_quotes(raw_lines):
74 74 """ Strip email quotation marks at the beginning of each line.
75 75
76 76 We don't do any more input transofrmations here because the main shell's
77 77 prefiltering handles other cases.
78 78 """
79 79 lines = [re.sub(r'^\s*(\s?>)+', '', l) for l in raw_lines]
80 80 return '\n'.join(lines) + '\n'
81 81
82 82
83 83 # These two functions are needed by the %paste/%cpaste magics. In practice
84 84 # they are basically methods (they take the shell as their first argument), but
85 85 # we leave them as standalone functions because eventually the magics
86 86 # themselves will become separate objects altogether. At that point, the
87 87 # magics will have access to the shell object, and these functions can be made
88 88 # methods of the magic object, but not of the shell.
89 89
90 90 def store_or_execute(shell, block, name):
91 91 """ Execute a block, or store it in a variable, per the user's request.
92 92 """
93 93 # Dedent and prefilter so what we store matches what is executed by
94 94 # run_cell.
95 95 b = shell.prefilter(textwrap.dedent(block))
96 96
97 97 if name:
98 98 # If storing it for further editing, run the prefilter on it
99 99 shell.user_ns[name] = SList(b.splitlines())
100 100 print "Block assigned to '%s'" % name
101 101 else:
102 102 shell.user_ns['pasted_block'] = b
103 103 shell.run_cell(b)
104 104
105 105
106 106 def rerun_pasted(shell, name='pasted_block'):
107 107 """ Rerun a previously pasted command.
108 108 """
109 109 b = shell.user_ns.get(name)
110 110
111 111 # Sanity checks
112 112 if b is None:
113 113 raise UsageError('No previous pasted block available')
114 114 if not isinstance(b, basestring):
115 115 raise UsageError(
116 116 "Variable 'pasted_block' is not a string, can't execute")
117 117
118 118 print "Re-executing '%s...' (%d chars)"% (b.split('\n',1)[0], len(b))
119 119 shell.run_cell(b)
120 120
121 121
122 122 #-----------------------------------------------------------------------------
123 123 # Main class
124 124 #-----------------------------------------------------------------------------
125 125
126 126 class TerminalInteractiveShell(InteractiveShell):
127 127
128 128 autoedit_syntax = CBool(False, config=True,
129 129 help="auto editing of files with syntax errors.")
130 130 banner = Unicode('')
131 131 banner1 = Unicode(default_banner, config=True,
132 132 help="""The part of the banner to be printed before the profile"""
133 133 )
134 134 banner2 = Unicode('', config=True,
135 135 help="""The part of the banner to be printed after the profile"""
136 136 )
137 137 confirm_exit = CBool(True, config=True,
138 138 help="""
139 139 Set to confirm when you try to exit IPython with an EOF (Control-D
140 140 in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
141 141 you can force a direct exit without any confirmation.""",
142 142 )
143 143 # This display_banner only controls whether or not self.show_banner()
144 144 # is called when mainloop/interact are called. The default is False
145 145 # because for the terminal based application, the banner behavior
146 146 # is controlled by Global.display_banner, which IPythonApp looks at
147 147 # to determine if *it* should call show_banner() by hand or not.
148 148 display_banner = CBool(False) # This isn't configurable!
149 149 embedded = CBool(False)
150 150 embedded_active = CBool(False)
151 151 editor = Unicode(get_default_editor(), config=True,
152 152 help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
153 153 )
154 154 pager = Unicode('less', config=True,
155 155 help="The shell program to be used for paging.")
156 156
157 157 screen_length = Integer(0, config=True,
158 158 help=
159 159 """Number of lines of your screen, used to control printing of very
160 160 long strings. Strings longer than this number of lines will be sent
161 161 through a pager instead of directly printed. The default value for
162 162 this is 0, which means IPython will auto-detect your screen size every
163 163 time it needs to print certain potentially long strings (this doesn't
164 164 change the behavior of the 'print' keyword, it's only triggered
165 165 internally). If for some reason this isn't working well (it needs
166 166 curses support), specify it yourself. Otherwise don't change the
167 167 default.""",
168 168 )
169 169 term_title = CBool(False, config=True,
170 170 help="Enable auto setting the terminal title."
171 171 )
172 172
173 173 # In the terminal, GUI control is done via PyOS_InputHook
174 174 from IPython.lib.inputhook import enable_gui
175 175 enable_gui = staticmethod(enable_gui)
176 176
177 177 def __init__(self, config=None, ipython_dir=None, profile_dir=None,
178 178 user_ns=None, user_module=None, custom_exceptions=((),None),
179 179 usage=None, banner1=None, banner2=None, display_banner=None):
180 180
181 181 super(TerminalInteractiveShell, self).__init__(
182 182 config=config, profile_dir=profile_dir, user_ns=user_ns,
183 183 user_module=user_module, custom_exceptions=custom_exceptions
184 184 )
185 185 # use os.system instead of utils.process.system by default,
186 186 # because piped system doesn't make sense in the Terminal:
187 187 self.system = self.system_raw
188 188
189 189 self.init_term_title()
190 190 self.init_usage(usage)
191 191 self.init_banner(banner1, banner2, display_banner)
192 192
193 193 #-------------------------------------------------------------------------
194 194 # Things related to the terminal
195 195 #-------------------------------------------------------------------------
196 196
197 197 @property
198 198 def usable_screen_length(self):
199 199 if self.screen_length == 0:
200 200 return 0
201 201 else:
202 202 num_lines_bot = self.separate_in.count('\n')+1
203 203 return self.screen_length - num_lines_bot
204 204
205 205 def init_term_title(self):
206 206 # Enable or disable the terminal title.
207 207 if self.term_title:
208 208 toggle_set_term_title(True)
209 209 set_term_title('IPython: ' + abbrev_cwd())
210 210 else:
211 211 toggle_set_term_title(False)
212 212
213 213 #-------------------------------------------------------------------------
214 214 # Things related to aliases
215 215 #-------------------------------------------------------------------------
216 216
217 217 def init_alias(self):
218 218 # The parent class defines aliases that can be safely used with any
219 219 # frontend.
220 220 super(TerminalInteractiveShell, self).init_alias()
221 221
222 222 # Now define aliases that only make sense on the terminal, because they
223 223 # need direct access to the console in a way that we can't emulate in
224 224 # GUI or web frontend
225 225 if os.name == 'posix':
226 226 aliases = [('clear', 'clear'), ('more', 'more'), ('less', 'less'),
227 227 ('man', 'man')]
228 228 elif os.name == 'nt':
229 229 aliases = [('cls', 'cls')]
230 230
231 231
232 232 for name, cmd in aliases:
233 233 self.alias_manager.define_alias(name, cmd)
234 234
235 235 #-------------------------------------------------------------------------
236 236 # Things related to the banner and usage
237 237 #-------------------------------------------------------------------------
238 238
239 239 def _banner1_changed(self):
240 240 self.compute_banner()
241 241
242 242 def _banner2_changed(self):
243 243 self.compute_banner()
244 244
245 245 def _term_title_changed(self, name, new_value):
246 246 self.init_term_title()
247 247
248 248 def init_banner(self, banner1, banner2, display_banner):
249 249 if banner1 is not None:
250 250 self.banner1 = banner1
251 251 if banner2 is not None:
252 252 self.banner2 = banner2
253 253 if display_banner is not None:
254 254 self.display_banner = display_banner
255 255 self.compute_banner()
256 256
257 257 def show_banner(self, banner=None):
258 258 if banner is None:
259 259 banner = self.banner
260 260 self.write(banner)
261 261
262 262 def compute_banner(self):
263 263 self.banner = self.banner1
264 264 if self.profile and self.profile != 'default':
265 265 self.banner += '\nIPython profile: %s\n' % self.profile
266 266 if self.banner2:
267 267 self.banner += '\n' + self.banner2
268 268
269 269 def init_usage(self, usage=None):
270 270 if usage is None:
271 271 self.usage = interactive_usage
272 272 else:
273 273 self.usage = usage
274 274
275 275 #-------------------------------------------------------------------------
276 276 # Mainloop and code execution logic
277 277 #-------------------------------------------------------------------------
278 278
279 279 def mainloop(self, display_banner=None):
280 280 """Start the mainloop.
281 281
282 282 If an optional banner argument is given, it will override the
283 283 internally created default banner.
284 284 """
285 285
286 286 with nested(self.builtin_trap, self.display_trap):
287 287
288 288 while 1:
289 289 try:
290 290 self.interact(display_banner=display_banner)
291 291 #self.interact_with_readline()
292 292 # XXX for testing of a readline-decoupled repl loop, call
293 293 # interact_with_readline above
294 294 break
295 295 except KeyboardInterrupt:
296 296 # this should not be necessary, but KeyboardInterrupt
297 297 # handling seems rather unpredictable...
298 298 self.write("\nKeyboardInterrupt in interact()\n")
299 299
300 300 def _replace_rlhist_multiline(self, source_raw, hlen_before_cell):
301 301 """Store multiple lines as a single entry in history"""
302 302
303 303 # do nothing without readline or disabled multiline
304 304 if not self.has_readline or not self.multiline_history:
305 305 return hlen_before_cell
306 306
307 307 # windows rl has no remove_history_item
308 308 if not hasattr(self.readline, "remove_history_item"):
309 309 return hlen_before_cell
310 310
311 311 # skip empty cells
312 312 if not source_raw.rstrip():
313 313 return hlen_before_cell
314 314
315 315 # nothing changed do nothing, e.g. when rl removes consecutive dups
316 316 hlen = self.readline.get_current_history_length()
317 317 if hlen == hlen_before_cell:
318 318 return hlen_before_cell
319 319
320 320 for i in range(hlen - hlen_before_cell):
321 321 self.readline.remove_history_item(hlen - i - 1)
322 stdin_encoding = sys.stdin.encoding or "utf-8"
322 stdin_encoding = py3compat.get_stream_enc(sys.stdin, 'utf-8')
323 323 self.readline.add_history(py3compat.unicode_to_str(source_raw.rstrip(),
324 324 stdin_encoding))
325 325 return self.readline.get_current_history_length()
326 326
327 327 def interact(self, display_banner=None):
328 328 """Closely emulate the interactive Python console."""
329 329
330 330 # batch run -> do not interact
331 331 if self.exit_now:
332 332 return
333 333
334 334 if display_banner is None:
335 335 display_banner = self.display_banner
336 336
337 337 if isinstance(display_banner, basestring):
338 338 self.show_banner(display_banner)
339 339 elif display_banner:
340 340 self.show_banner()
341 341
342 342 more = False
343 343
344 344 if self.has_readline:
345 345 self.readline_startup_hook(self.pre_readline)
346 346 hlen_b4_cell = self.readline.get_current_history_length()
347 347 else:
348 348 hlen_b4_cell = 0
349 349 # exit_now is set by a call to %Exit or %Quit, through the
350 350 # ask_exit callback.
351 351
352 352 while not self.exit_now:
353 353 self.hooks.pre_prompt_hook()
354 354 if more:
355 355 try:
356 356 prompt = self.prompt_manager.render('in2')
357 357 except:
358 358 self.showtraceback()
359 359 if self.autoindent:
360 360 self.rl_do_indent = True
361 361
362 362 else:
363 363 try:
364 364 prompt = self.separate_in + self.prompt_manager.render('in')
365 365 except:
366 366 self.showtraceback()
367 367 try:
368 368 line = self.raw_input(prompt)
369 369 if self.exit_now:
370 370 # quick exit on sys.std[in|out] close
371 371 break
372 372 if self.autoindent:
373 373 self.rl_do_indent = False
374 374
375 375 except KeyboardInterrupt:
376 376 #double-guard against keyboardinterrupts during kbdint handling
377 377 try:
378 378 self.write('\nKeyboardInterrupt\n')
379 379 source_raw = self.input_splitter.source_raw_reset()[1]
380 380 hlen_b4_cell = \
381 381 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
382 382 more = False
383 383 except KeyboardInterrupt:
384 384 pass
385 385 except EOFError:
386 386 if self.autoindent:
387 387 self.rl_do_indent = False
388 388 if self.has_readline:
389 389 self.readline_startup_hook(None)
390 390 self.write('\n')
391 391 self.exit()
392 392 except bdb.BdbQuit:
393 393 warn('The Python debugger has exited with a BdbQuit exception.\n'
394 394 'Because of how pdb handles the stack, it is impossible\n'
395 395 'for IPython to properly format this particular exception.\n'
396 396 'IPython will resume normal operation.')
397 397 except:
398 398 # exceptions here are VERY RARE, but they can be triggered
399 399 # asynchronously by signal handlers, for example.
400 400 self.showtraceback()
401 401 else:
402 402 self.input_splitter.push(line)
403 403 more = self.input_splitter.push_accepts_more()
404 404 if (self.SyntaxTB.last_syntax_error and
405 405 self.autoedit_syntax):
406 406 self.edit_syntax_error()
407 407 if not more:
408 408 source_raw = self.input_splitter.source_raw_reset()[1]
409 409 self.run_cell(source_raw, store_history=True)
410 410 hlen_b4_cell = \
411 411 self._replace_rlhist_multiline(source_raw, hlen_b4_cell)
412 412
413 413 # Turn off the exit flag, so the mainloop can be restarted if desired
414 414 self.exit_now = False
415 415
416 416 def raw_input(self, prompt=''):
417 417 """Write a prompt and read a line.
418 418
419 419 The returned line does not include the trailing newline.
420 420 When the user enters the EOF key sequence, EOFError is raised.
421 421
422 422 Optional inputs:
423 423
424 424 - prompt(''): a string to be printed to prompt the user.
425 425
426 426 - continue_prompt(False): whether this line is the first one or a
427 427 continuation in a sequence of inputs.
428 428 """
429 429 # Code run by the user may have modified the readline completer state.
430 430 # We must ensure that our completer is back in place.
431 431
432 432 if self.has_readline:
433 433 self.set_readline_completer()
434 434
435 435 try:
436 436 line = py3compat.str_to_unicode(self.raw_input_original(prompt))
437 437 except ValueError:
438 438 warn("\n********\nYou or a %run:ed script called sys.stdin.close()"
439 439 " or sys.stdout.close()!\nExiting IPython!")
440 440 self.ask_exit()
441 441 return ""
442 442
443 443 # Try to be reasonably smart about not re-indenting pasted input more
444 444 # than necessary. We do this by trimming out the auto-indent initial
445 445 # spaces, if the user's actual input started itself with whitespace.
446 446 if self.autoindent:
447 447 if num_ini_spaces(line) > self.indent_current_nsp:
448 448 line = line[self.indent_current_nsp:]
449 449 self.indent_current_nsp = 0
450 450
451 451 return line
452 452
453 453 #-------------------------------------------------------------------------
454 454 # Methods to support auto-editing of SyntaxErrors.
455 455 #-------------------------------------------------------------------------
456 456
457 457 def edit_syntax_error(self):
458 458 """The bottom half of the syntax error handler called in the main loop.
459 459
460 460 Loop until syntax error is fixed or user cancels.
461 461 """
462 462
463 463 while self.SyntaxTB.last_syntax_error:
464 464 # copy and clear last_syntax_error
465 465 err = self.SyntaxTB.clear_err_state()
466 466 if not self._should_recompile(err):
467 467 return
468 468 try:
469 469 # may set last_syntax_error again if a SyntaxError is raised
470 470 self.safe_execfile(err.filename,self.user_ns)
471 471 except:
472 472 self.showtraceback()
473 473 else:
474 474 try:
475 475 f = open(err.filename)
476 476 try:
477 477 # This should be inside a display_trap block and I
478 478 # think it is.
479 479 sys.displayhook(f.read())
480 480 finally:
481 481 f.close()
482 482 except:
483 483 self.showtraceback()
484 484
485 485 def _should_recompile(self,e):
486 486 """Utility routine for edit_syntax_error"""
487 487
488 488 if e.filename in ('<ipython console>','<input>','<string>',
489 489 '<console>','<BackgroundJob compilation>',
490 490 None):
491 491
492 492 return False
493 493 try:
494 494 if (self.autoedit_syntax and
495 495 not self.ask_yes_no('Return to editor to correct syntax error? '
496 496 '[Y/n] ','y')):
497 497 return False
498 498 except EOFError:
499 499 return False
500 500
501 501 def int0(x):
502 502 try:
503 503 return int(x)
504 504 except TypeError:
505 505 return 0
506 506 # always pass integer line and offset values to editor hook
507 507 try:
508 508 self.hooks.fix_error_editor(e.filename,
509 509 int0(e.lineno),int0(e.offset),e.msg)
510 510 except TryNext:
511 511 warn('Could not open editor')
512 512 return False
513 513 return True
514 514
515 515 #-------------------------------------------------------------------------
516 516 # Things related to exiting
517 517 #-------------------------------------------------------------------------
518 518
519 519 def ask_exit(self):
520 520 """ Ask the shell to exit. Can be overiden and used as a callback. """
521 521 self.exit_now = True
522 522
523 523 def exit(self):
524 524 """Handle interactive exit.
525 525
526 526 This method calls the ask_exit callback."""
527 527 if self.confirm_exit:
528 528 if self.ask_yes_no('Do you really want to exit ([y]/n)?','y'):
529 529 self.ask_exit()
530 530 else:
531 531 self.ask_exit()
532 532
533 533 #------------------------------------------------------------------------
534 534 # Magic overrides
535 535 #------------------------------------------------------------------------
536 536 # Once the base class stops inheriting from magic, this code needs to be
537 537 # moved into a separate machinery as well. For now, at least isolate here
538 538 # the magics which this class needs to implement differently from the base
539 539 # class, or that are unique to it.
540 540
541 541 def magic_autoindent(self, parameter_s = ''):
542 542 """Toggle autoindent on/off (if available)."""
543 543
544 544 self.shell.set_autoindent()
545 545 print "Automatic indentation is:",['OFF','ON'][self.shell.autoindent]
546 546
547 547 @skip_doctest
548 548 def magic_cpaste(self, parameter_s=''):
549 549 """Paste & execute a pre-formatted code block from clipboard.
550 550
551 551 You must terminate the block with '--' (two minus-signs) or Ctrl-D
552 552 alone on the line. You can also provide your own sentinel with '%paste
553 553 -s %%' ('%%' is the new sentinel for this operation)
554 554
555 555 The block is dedented prior to execution to enable execution of method
556 556 definitions. '>' and '+' characters at the beginning of a line are
557 557 ignored, to allow pasting directly from e-mails, diff files and
558 558 doctests (the '...' continuation prompt is also stripped). The
559 559 executed block is also assigned to variable named 'pasted_block' for
560 560 later editing with '%edit pasted_block'.
561 561
562 562 You can also pass a variable name as an argument, e.g. '%cpaste foo'.
563 563 This assigns the pasted block to variable 'foo' as string, without
564 564 dedenting or executing it (preceding >>> and + is still stripped)
565 565
566 566 '%cpaste -r' re-executes the block previously entered by cpaste.
567 567
568 568 Do not be alarmed by garbled output on Windows (it's a readline bug).
569 569 Just press enter and type -- (and press enter again) and the block
570 570 will be what was just pasted.
571 571
572 572 IPython statements (magics, shell escapes) are not supported (yet).
573 573
574 574 See also
575 575 --------
576 576 paste: automatically pull code from clipboard.
577 577
578 578 Examples
579 579 --------
580 580 ::
581 581
582 582 In [8]: %cpaste
583 583 Pasting code; enter '--' alone on the line to stop.
584 584 :>>> a = ["world!", "Hello"]
585 585 :>>> print " ".join(sorted(a))
586 586 :--
587 587 Hello world!
588 588 """
589 589
590 590 opts, name = self.parse_options(parameter_s, 'rs:', mode='string')
591 591 if 'r' in opts:
592 592 rerun_pasted(self.shell)
593 593 return
594 594
595 595 sentinel = opts.get('s', '--')
596 596 block = strip_email_quotes(get_pasted_lines(sentinel))
597 597 store_or_execute(self.shell, block, name)
598 598
599 599 def magic_paste(self, parameter_s=''):
600 600 """Paste & execute a pre-formatted code block from clipboard.
601 601
602 602 The text is pulled directly from the clipboard without user
603 603 intervention and printed back on the screen before execution (unless
604 604 the -q flag is given to force quiet mode).
605 605
606 606 The block is dedented prior to execution to enable execution of method
607 607 definitions. '>' and '+' characters at the beginning of a line are
608 608 ignored, to allow pasting directly from e-mails, diff files and
609 609 doctests (the '...' continuation prompt is also stripped). The
610 610 executed block is also assigned to variable named 'pasted_block' for
611 611 later editing with '%edit pasted_block'.
612 612
613 613 You can also pass a variable name as an argument, e.g. '%paste foo'.
614 614 This assigns the pasted block to variable 'foo' as string, without
615 615 dedenting or executing it (preceding >>> and + is still stripped)
616 616
617 617 Options
618 618 -------
619 619
620 620 -r: re-executes the block previously entered by cpaste.
621 621
622 622 -q: quiet mode: do not echo the pasted text back to the terminal.
623 623
624 624 IPython statements (magics, shell escapes) are not supported (yet).
625 625
626 626 See also
627 627 --------
628 628 cpaste: manually paste code into terminal until you mark its end.
629 629 """
630 630 opts, name = self.parse_options(parameter_s, 'rq', mode='string')
631 631 if 'r' in opts:
632 632 rerun_pasted(self.shell)
633 633 return
634 634 try:
635 635 text = self.shell.hooks.clipboard_get()
636 636 block = strip_email_quotes(text.splitlines())
637 637 except TryNext as clipboard_exc:
638 638 message = getattr(clipboard_exc, 'args')
639 639 if message:
640 640 error(message[0])
641 641 else:
642 642 error('Could not get text from the clipboard.')
643 643 return
644 644
645 645 # By default, echo back to terminal unless quiet mode is requested
646 646 if 'q' not in opts:
647 647 write = self.shell.write
648 648 write(self.shell.pycolorize(block))
649 649 if not block.endswith('\n'):
650 650 write('\n')
651 651 write("## -- End pasted text --\n")
652 652
653 653 store_or_execute(self.shell, block, name)
654 654
655 655 # Class-level: add a '%cls' magic only on Windows
656 656 if sys.platform == 'win32':
657 657 def magic_cls(self, s):
658 658 """Clear screen.
659 659 """
660 660 os.system("cls")
661 661
662 662 def showindentationerror(self):
663 663 super(TerminalInteractiveShell, self).showindentationerror()
664 664 print("If you want to paste code into IPython, try the "
665 665 "%paste and %cpaste magic functions.")
666 666
667 667
668 668 InteractiveShellABC.register(TerminalInteractiveShell)
@@ -1,321 +1,321 b''
1 1 # encoding: utf-8
2 2 """
3 3 IO related utilities.
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 from __future__ import print_function
13 13
14 14 #-----------------------------------------------------------------------------
15 15 # Imports
16 16 #-----------------------------------------------------------------------------
17 17 import sys
18 18 import tempfile
19 19
20 20 #-----------------------------------------------------------------------------
21 21 # Code
22 22 #-----------------------------------------------------------------------------
23 23
24 24
25 25 class IOStream:
26 26
27 27 def __init__(self,stream, fallback=None):
28 28 if not hasattr(stream,'write') or not hasattr(stream,'flush'):
29 29 if fallback is not None:
30 30 stream = fallback
31 31 else:
32 32 raise ValueError("fallback required, but not specified")
33 33 self.stream = stream
34 34 self._swrite = stream.write
35 35
36 36 # clone all methods not overridden:
37 37 def clone(meth):
38 38 return not hasattr(self, meth) and not meth.startswith('_')
39 39 for meth in filter(clone, dir(stream)):
40 40 setattr(self, meth, getattr(stream, meth))
41 41
42 42 def write(self,data):
43 43 try:
44 44 self._swrite(data)
45 45 except:
46 46 try:
47 47 # print handles some unicode issues which may trip a plain
48 48 # write() call. Emulate write() by using an empty end
49 49 # argument.
50 50 print(data, end='', file=self.stream)
51 51 except:
52 52 # if we get here, something is seriously broken.
53 53 print('ERROR - failed to write data to stream:', self.stream,
54 54 file=sys.stderr)
55 55
56 56 def writelines(self, lines):
57 57 if isinstance(lines, basestring):
58 58 lines = [lines]
59 59 for line in lines:
60 60 self.write(line)
61 61
62 62 # This class used to have a writeln method, but regular files and streams
63 63 # in Python don't have this method. We need to keep this completely
64 64 # compatible so we removed it.
65 65
66 66 @property
67 67 def closed(self):
68 68 return self.stream.closed
69 69
70 70 def close(self):
71 71 pass
72 72
73 73
74 74 class IOTerm:
75 75 """ Term holds the file or file-like objects for handling I/O operations.
76 76
77 77 These are normally just sys.stdin, sys.stdout and sys.stderr but for
78 78 Windows they can can replaced to allow editing the strings before they are
79 79 displayed."""
80 80
81 81 # In the future, having IPython channel all its I/O operations through
82 82 # this class will make it easier to embed it into other environments which
83 83 # are not a normal terminal (such as a GUI-based shell)
84 84 def __init__(self, stdin=None, stdout=None, stderr=None):
85 85 self.stdin = IOStream(stdin, sys.stdin)
86 86 self.stdout = IOStream(stdout, sys.stdout)
87 87 self.stderr = IOStream(stderr, sys.stderr)
88 88
89 89 # setup stdin/stdout/stderr to sys.stdin/sys.stdout/sys.stderr
90 stdin = IOStream(sys.stdin)
91 stdout = IOStream(sys.stdout)
92 stderr = IOStream(sys.stderr)
90 stdin = sys.stdin if not sys.stdin else IOStream(sys.stdin)
91 stdout = sys.stdout if not sys.stdout else IOStream(sys.stdout)
92 stderr = sys.stderr if not sys.stderr else IOStream(sys.stderr)
93 93
94 94
95 95 class Tee(object):
96 96 """A class to duplicate an output stream to stdout/err.
97 97
98 98 This works in a manner very similar to the Unix 'tee' command.
99 99
100 100 When the object is closed or deleted, it closes the original file given to
101 101 it for duplication.
102 102 """
103 103 # Inspired by:
104 104 # http://mail.python.org/pipermail/python-list/2007-May/442737.html
105 105
106 106 def __init__(self, file_or_name, mode="w", channel='stdout'):
107 107 """Construct a new Tee object.
108 108
109 109 Parameters
110 110 ----------
111 111 file_or_name : filename or open filehandle (writable)
112 112 File that will be duplicated
113 113
114 114 mode : optional, valid mode for open().
115 115 If a filename was give, open with this mode.
116 116
117 117 channel : str, one of ['stdout', 'stderr']
118 118 """
119 119 if channel not in ['stdout', 'stderr']:
120 120 raise ValueError('Invalid channel spec %s' % channel)
121 121
122 122 if hasattr(file_or_name, 'write') and hasattr(file_or_name, 'seek'):
123 123 self.file = file_or_name
124 124 else:
125 125 self.file = open(file_or_name, mode)
126 126 self.channel = channel
127 127 self.ostream = getattr(sys, channel)
128 128 setattr(sys, channel, self)
129 129 self._closed = False
130 130
131 131 def close(self):
132 132 """Close the file and restore the channel."""
133 133 self.flush()
134 134 setattr(sys, self.channel, self.ostream)
135 135 self.file.close()
136 136 self._closed = True
137 137
138 138 def write(self, data):
139 139 """Write data to both channels."""
140 140 self.file.write(data)
141 141 self.ostream.write(data)
142 142 self.ostream.flush()
143 143
144 144 def flush(self):
145 145 """Flush both channels."""
146 146 self.file.flush()
147 147 self.ostream.flush()
148 148
149 149 def __del__(self):
150 150 if not self._closed:
151 151 self.close()
152 152
153 153
154 154 def file_read(filename):
155 155 """Read a file and close it. Returns the file source."""
156 156 fobj = open(filename,'r');
157 157 source = fobj.read();
158 158 fobj.close()
159 159 return source
160 160
161 161
162 162 def file_readlines(filename):
163 163 """Read a file and close it. Returns the file source using readlines()."""
164 164 fobj = open(filename,'r');
165 165 lines = fobj.readlines();
166 166 fobj.close()
167 167 return lines
168 168
169 169
170 170 def raw_input_multi(header='', ps1='==> ', ps2='..> ',terminate_str = '.'):
171 171 """Take multiple lines of input.
172 172
173 173 A list with each line of input as a separate element is returned when a
174 174 termination string is entered (defaults to a single '.'). Input can also
175 175 terminate via EOF (^D in Unix, ^Z-RET in Windows).
176 176
177 177 Lines of input which end in \\ are joined into single entries (and a
178 178 secondary continuation prompt is issued as long as the user terminates
179 179 lines with \\). This allows entering very long strings which are still
180 180 meant to be treated as single entities.
181 181 """
182 182
183 183 try:
184 184 if header:
185 185 header += '\n'
186 186 lines = [raw_input(header + ps1)]
187 187 except EOFError:
188 188 return []
189 189 terminate = [terminate_str]
190 190 try:
191 191 while lines[-1:] != terminate:
192 192 new_line = raw_input(ps1)
193 193 while new_line.endswith('\\'):
194 194 new_line = new_line[:-1] + raw_input(ps2)
195 195 lines.append(new_line)
196 196
197 197 return lines[:-1] # don't return the termination command
198 198 except EOFError:
199 199 print()
200 200 return lines
201 201
202 202
203 203 def raw_input_ext(prompt='', ps2='... '):
204 204 """Similar to raw_input(), but accepts extended lines if input ends with \\."""
205 205
206 206 line = raw_input(prompt)
207 207 while line.endswith('\\'):
208 208 line = line[:-1] + raw_input(ps2)
209 209 return line
210 210
211 211
212 212 def ask_yes_no(prompt,default=None):
213 213 """Asks a question and returns a boolean (y/n) answer.
214 214
215 215 If default is given (one of 'y','n'), it is used if the user input is
216 216 empty. Otherwise the question is repeated until an answer is given.
217 217
218 218 An EOF is treated as the default answer. If there is no default, an
219 219 exception is raised to prevent infinite loops.
220 220
221 221 Valid answers are: y/yes/n/no (match is not case sensitive)."""
222 222
223 223 answers = {'y':True,'n':False,'yes':True,'no':False}
224 224 ans = None
225 225 while ans not in answers.keys():
226 226 try:
227 227 ans = raw_input(prompt+' ').lower()
228 228 if not ans: # response was an empty string
229 229 ans = default
230 230 except KeyboardInterrupt:
231 231 pass
232 232 except EOFError:
233 233 if default in answers.keys():
234 234 ans = default
235 235 print()
236 236 else:
237 237 raise
238 238
239 239 return answers[ans]
240 240
241 241
242 242 class NLprinter:
243 243 """Print an arbitrarily nested list, indicating index numbers.
244 244
245 245 An instance of this class called nlprint is available and callable as a
246 246 function.
247 247
248 248 nlprint(list,indent=' ',sep=': ') -> prints indenting each level by 'indent'
249 249 and using 'sep' to separate the index from the value. """
250 250
251 251 def __init__(self):
252 252 self.depth = 0
253 253
254 254 def __call__(self,lst,pos='',**kw):
255 255 """Prints the nested list numbering levels."""
256 256 kw.setdefault('indent',' ')
257 257 kw.setdefault('sep',': ')
258 258 kw.setdefault('start',0)
259 259 kw.setdefault('stop',len(lst))
260 260 # we need to remove start and stop from kw so they don't propagate
261 261 # into a recursive call for a nested list.
262 262 start = kw['start']; del kw['start']
263 263 stop = kw['stop']; del kw['stop']
264 264 if self.depth == 0 and 'header' in kw.keys():
265 265 print(kw['header'])
266 266
267 267 for idx in range(start,stop):
268 268 elem = lst[idx]
269 269 newpos = pos + str(idx)
270 270 if type(elem)==type([]):
271 271 self.depth += 1
272 272 self.__call__(elem, newpos+",", **kw)
273 273 self.depth -= 1
274 274 else:
275 275 print(kw['indent']*self.depth + newpos + kw["sep"] + repr(elem))
276 276
277 277 nlprint = NLprinter()
278 278
279 279
280 280 def temp_pyfile(src, ext='.py'):
281 281 """Make a temporary python file, return filename and filehandle.
282 282
283 283 Parameters
284 284 ----------
285 285 src : string or list of strings (no need for ending newlines if list)
286 286 Source code to be written to the file.
287 287
288 288 ext : optional, string
289 289 Extension for the generated file.
290 290
291 291 Returns
292 292 -------
293 293 (filename, open filehandle)
294 294 It is the caller's responsibility to close the open file and unlink it.
295 295 """
296 296 fname = tempfile.mkstemp(ext)[1]
297 297 f = open(fname,'w')
298 298 f.write(src)
299 299 f.flush()
300 300 return fname, f
301 301
302 302
303 303 def raw_print(*args, **kw):
304 304 """Raw print to sys.__stdout__, otherwise identical interface to print()."""
305 305
306 306 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
307 307 file=sys.__stdout__)
308 308 sys.__stdout__.flush()
309 309
310 310
311 311 def raw_print_err(*args, **kw):
312 312 """Raw print to sys.__stderr__, otherwise identical interface to print()."""
313 313
314 314 print(*args, sep=kw.get('sep', ' '), end=kw.get('end', '\n'),
315 315 file=sys.__stderr__)
316 316 sys.__stderr__.flush()
317 317
318 318
319 319 # Short aliases for quick debugging, do NOT use these in production code.
320 320 rprint = raw_print
321 321 rprinte = raw_print_err
@@ -1,175 +1,183 b''
1 1 # coding: utf-8
2 2 """Compatibility tricks for Python 3. Mainly to do with unicode."""
3 3 import __builtin__
4 4 import functools
5 5 import sys
6 6 import re
7 7 import types
8 8
9 9 orig_open = open
10 10
11 11 def no_code(x, encoding=None):
12 12 return x
13 13
14 # to deal with the possibility of sys.std* not being a stream at all
15 def get_stream_enc(stream, default=None):
16 if not hasattr(stream, 'encoding') or not stream.encoding:
17 return default
18 else:
19 return stream.encoding
20
14 21 def decode(s, encoding=None):
15 encoding = encoding or sys.stdin.encoding or sys.getdefaultencoding()
22 encoding = get_stream_enc(sys.stdin, encoding) or sys.getdefaultencoding()
16 23 return s.decode(encoding, "replace")
17 24
18 25 def encode(u, encoding=None):
19 encoding = encoding or sys.stdin.encoding or sys.getdefaultencoding()
26 encoding = get_stream_enc(sys.stdin, encoding) or sys.getdefaultencoding()
20 27 return u.encode(encoding, "replace")
21
28
29
22 30 def cast_unicode(s, encoding=None):
23 31 if isinstance(s, bytes):
24 32 return decode(s, encoding)
25 33 return s
26 34
27 35 def cast_bytes(s, encoding=None):
28 36 if not isinstance(s, bytes):
29 37 return encode(s, encoding)
30 38 return s
31 39
32 40 def _modify_str_or_docstring(str_change_func):
33 41 @functools.wraps(str_change_func)
34 42 def wrapper(func_or_str):
35 43 if isinstance(func_or_str, basestring):
36 44 func = None
37 45 doc = func_or_str
38 46 else:
39 47 func = func_or_str
40 48 doc = func.__doc__
41 49
42 50 doc = str_change_func(doc)
43 51
44 52 if func:
45 53 func.__doc__ = doc
46 54 return func
47 55 return doc
48 56 return wrapper
49 57
50 58 if sys.version_info[0] >= 3:
51 59 PY3 = True
52 60
53 61 input = input
54 62 builtin_mod_name = "builtins"
55 63
56 64 str_to_unicode = no_code
57 65 unicode_to_str = no_code
58 66 str_to_bytes = encode
59 67 bytes_to_str = decode
60 68 cast_bytes_py2 = no_code
61 69
62 70 def isidentifier(s, dotted=False):
63 71 if dotted:
64 72 return all(isidentifier(a) for a in s.split("."))
65 73 return s.isidentifier()
66 74
67 75 open = orig_open
68 76
69 77 MethodType = types.MethodType
70 78
71 79 def execfile(fname, glob, loc=None):
72 80 loc = loc if (loc is not None) else glob
73 81 exec compile(open(fname, 'rb').read(), fname, 'exec') in glob, loc
74 82
75 83 # Refactor print statements in doctests.
76 84 _print_statement_re = re.compile(r"\bprint (?P<expr>.*)$", re.MULTILINE)
77 85 def _print_statement_sub(match):
78 86 expr = match.groups('expr')
79 87 return "print(%s)" % expr
80 88
81 89 @_modify_str_or_docstring
82 90 def doctest_refactor_print(doc):
83 91 """Refactor 'print x' statements in a doctest to print(x) style. 2to3
84 92 unfortunately doesn't pick up on our doctests.
85 93
86 94 Can accept a string or a function, so it can be used as a decorator."""
87 95 return _print_statement_re.sub(_print_statement_sub, doc)
88 96
89 97 # Abstract u'abc' syntax:
90 98 @_modify_str_or_docstring
91 99 def u_format(s):
92 100 """"{u}'abc'" --> "'abc'" (Python 3)
93 101
94 102 Accepts a string or a function, so it can be used as a decorator."""
95 103 return s.format(u='')
96 104
97 105 else:
98 106 PY3 = False
99 107
100 108 input = raw_input
101 109 builtin_mod_name = "__builtin__"
102 110
103 111 str_to_unicode = decode
104 112 unicode_to_str = encode
105 113 str_to_bytes = no_code
106 114 bytes_to_str = no_code
107 115 cast_bytes_py2 = cast_bytes
108 116
109 117 import re
110 118 _name_re = re.compile(r"[a-zA-Z_][a-zA-Z0-9_]*$")
111 119 def isidentifier(s, dotted=False):
112 120 if dotted:
113 121 return all(isidentifier(a) for a in s.split("."))
114 122 return bool(_name_re.match(s))
115 123
116 124 class open(object):
117 125 """Wrapper providing key part of Python 3 open() interface."""
118 126 def __init__(self, fname, mode="r", encoding="utf-8"):
119 127 self.f = orig_open(fname, mode)
120 128 self.enc = encoding
121 129
122 130 def write(self, s):
123 131 return self.f.write(s.encode(self.enc))
124 132
125 133 def read(self, size=-1):
126 134 return self.f.read(size).decode(self.enc)
127 135
128 136 def close(self):
129 137 return self.f.close()
130 138
131 139 def __enter__(self):
132 140 return self
133 141
134 142 def __exit__(self, etype, value, traceback):
135 143 self.f.close()
136 144
137 145 def MethodType(func, instance):
138 146 return types.MethodType(func, instance, type(instance))
139 147
140 148 # don't override system execfile on 2.x:
141 149 execfile = execfile
142 150
143 151 def doctest_refactor_print(func_or_str):
144 152 return func_or_str
145 153
146 154
147 155 # Abstract u'abc' syntax:
148 156 @_modify_str_or_docstring
149 157 def u_format(s):
150 158 """"{u}'abc'" --> "u'abc'" (Python 2)
151 159
152 160 Accepts a string or a function, so it can be used as a decorator."""
153 161 return s.format(u='u')
154 162
155 163 if sys.platform == 'win32':
156 164 def execfile(fname, glob=None, loc=None):
157 165 loc = loc if (loc is not None) else glob
158 166 # The rstrip() is necessary b/c trailing whitespace in files will
159 167 # cause an IndentationError in Python 2.6 (this was fixed in 2.7,
160 168 # but we still support 2.6). See issue 1027.
161 169 scripttext = __builtin__.open(fname).read().rstrip() + '\n'
162 170 # compile converts unicode filename to str assuming
163 171 # ascii. Let's do the conversion before calling compile
164 172 if isinstance(fname, unicode):
165 173 filename = unicode_to_str(fname)
166 174 else:
167 175 filename = fname
168 176 exec compile(scripttext, filename, 'exec') in glob, loc
169 177 else:
170 178 def execfile(fname, *where):
171 179 if isinstance(fname, unicode):
172 180 filename = fname.encode(sys.getfilesystemencoding())
173 181 else:
174 182 filename = fname
175 183 __builtin__.execfile(filename, *where)
@@ -1,760 +1,760 b''
1 1 # encoding: utf-8
2 2 """
3 3 Utilities for working with strings and text.
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 __main__
18 18
19 19 import locale
20 20 import os
21 21 import re
22 22 import shutil
23 23 import sys
24 24 import textwrap
25 25 from string import Formatter
26 26
27 27 from IPython.external.path import path
28 28 from IPython.testing.skipdoctest import skip_doctest_py3
29 29 from IPython.utils import py3compat
30 30 from IPython.utils.io import nlprint
31 31 from IPython.utils.data import flatten
32 32
33 33 #-----------------------------------------------------------------------------
34 34 # Code
35 35 #-----------------------------------------------------------------------------
36 36
37 37 # Less conservative replacement for sys.getdefaultencoding, that will try
38 38 # to match the environment.
39 39 # Defined here as central function, so if we find better choices, we
40 40 # won't need to make changes all over IPython.
41 41 def getdefaultencoding():
42 42 """Return IPython's guess for the default encoding for bytes as text.
43 43
44 44 Asks for stdin.encoding first, to match the calling Terminal, but that
45 45 is often None for subprocesses. Fall back on locale.getpreferredencoding()
46 46 which should be a sensible platform default (that respects LANG environment),
47 47 and finally to sys.getdefaultencoding() which is the most conservative option,
48 48 and usually ASCII.
49 49 """
50 enc = sys.stdin.encoding
50 enc = py3compat.get_stream_enc(sys.stdin)
51 51 if not enc or enc=='ascii':
52 52 try:
53 53 # There are reports of getpreferredencoding raising errors
54 54 # in some cases, which may well be fixed, but let's be conservative here.
55 55 enc = locale.getpreferredencoding()
56 56 except Exception:
57 57 pass
58 58 return enc or sys.getdefaultencoding()
59 59
60 60 def unquote_ends(istr):
61 61 """Remove a single pair of quotes from the endpoints of a string."""
62 62
63 63 if not istr:
64 64 return istr
65 65 if (istr[0]=="'" and istr[-1]=="'") or \
66 66 (istr[0]=='"' and istr[-1]=='"'):
67 67 return istr[1:-1]
68 68 else:
69 69 return istr
70 70
71 71
72 72 class LSString(str):
73 73 """String derivative with a special access attributes.
74 74
75 75 These are normal strings, but with the special attributes:
76 76
77 77 .l (or .list) : value as list (split on newlines).
78 78 .n (or .nlstr): original value (the string itself).
79 79 .s (or .spstr): value as whitespace-separated string.
80 80 .p (or .paths): list of path objects
81 81
82 82 Any values which require transformations are computed only once and
83 83 cached.
84 84
85 85 Such strings are very useful to efficiently interact with the shell, which
86 86 typically only understands whitespace-separated options for commands."""
87 87
88 88 def get_list(self):
89 89 try:
90 90 return self.__list
91 91 except AttributeError:
92 92 self.__list = self.split('\n')
93 93 return self.__list
94 94
95 95 l = list = property(get_list)
96 96
97 97 def get_spstr(self):
98 98 try:
99 99 return self.__spstr
100 100 except AttributeError:
101 101 self.__spstr = self.replace('\n',' ')
102 102 return self.__spstr
103 103
104 104 s = spstr = property(get_spstr)
105 105
106 106 def get_nlstr(self):
107 107 return self
108 108
109 109 n = nlstr = property(get_nlstr)
110 110
111 111 def get_paths(self):
112 112 try:
113 113 return self.__paths
114 114 except AttributeError:
115 115 self.__paths = [path(p) for p in self.split('\n') if os.path.exists(p)]
116 116 return self.__paths
117 117
118 118 p = paths = property(get_paths)
119 119
120 120 # FIXME: We need to reimplement type specific displayhook and then add this
121 121 # back as a custom printer. This should also be moved outside utils into the
122 122 # core.
123 123
124 124 # def print_lsstring(arg):
125 125 # """ Prettier (non-repr-like) and more informative printer for LSString """
126 126 # print "LSString (.p, .n, .l, .s available). Value:"
127 127 # print arg
128 128 #
129 129 #
130 130 # print_lsstring = result_display.when_type(LSString)(print_lsstring)
131 131
132 132
133 133 class SList(list):
134 134 """List derivative with a special access attributes.
135 135
136 136 These are normal lists, but with the special attributes:
137 137
138 138 .l (or .list) : value as list (the list itself).
139 139 .n (or .nlstr): value as a string, joined on newlines.
140 140 .s (or .spstr): value as a string, joined on spaces.
141 141 .p (or .paths): list of path objects
142 142
143 143 Any values which require transformations are computed only once and
144 144 cached."""
145 145
146 146 def get_list(self):
147 147 return self
148 148
149 149 l = list = property(get_list)
150 150
151 151 def get_spstr(self):
152 152 try:
153 153 return self.__spstr
154 154 except AttributeError:
155 155 self.__spstr = ' '.join(self)
156 156 return self.__spstr
157 157
158 158 s = spstr = property(get_spstr)
159 159
160 160 def get_nlstr(self):
161 161 try:
162 162 return self.__nlstr
163 163 except AttributeError:
164 164 self.__nlstr = '\n'.join(self)
165 165 return self.__nlstr
166 166
167 167 n = nlstr = property(get_nlstr)
168 168
169 169 def get_paths(self):
170 170 try:
171 171 return self.__paths
172 172 except AttributeError:
173 173 self.__paths = [path(p) for p in self if os.path.exists(p)]
174 174 return self.__paths
175 175
176 176 p = paths = property(get_paths)
177 177
178 178 def grep(self, pattern, prune = False, field = None):
179 179 """ Return all strings matching 'pattern' (a regex or callable)
180 180
181 181 This is case-insensitive. If prune is true, return all items
182 182 NOT matching the pattern.
183 183
184 184 If field is specified, the match must occur in the specified
185 185 whitespace-separated field.
186 186
187 187 Examples::
188 188
189 189 a.grep( lambda x: x.startswith('C') )
190 190 a.grep('Cha.*log', prune=1)
191 191 a.grep('chm', field=-1)
192 192 """
193 193
194 194 def match_target(s):
195 195 if field is None:
196 196 return s
197 197 parts = s.split()
198 198 try:
199 199 tgt = parts[field]
200 200 return tgt
201 201 except IndexError:
202 202 return ""
203 203
204 204 if isinstance(pattern, basestring):
205 205 pred = lambda x : re.search(pattern, x, re.IGNORECASE)
206 206 else:
207 207 pred = pattern
208 208 if not prune:
209 209 return SList([el for el in self if pred(match_target(el))])
210 210 else:
211 211 return SList([el for el in self if not pred(match_target(el))])
212 212
213 213 def fields(self, *fields):
214 214 """ Collect whitespace-separated fields from string list
215 215
216 216 Allows quick awk-like usage of string lists.
217 217
218 218 Example data (in var a, created by 'a = !ls -l')::
219 219 -rwxrwxrwx 1 ville None 18 Dec 14 2006 ChangeLog
220 220 drwxrwxrwx+ 6 ville None 0 Oct 24 18:05 IPython
221 221
222 222 a.fields(0) is ['-rwxrwxrwx', 'drwxrwxrwx+']
223 223 a.fields(1,0) is ['1 -rwxrwxrwx', '6 drwxrwxrwx+']
224 224 (note the joining by space).
225 225 a.fields(-1) is ['ChangeLog', 'IPython']
226 226
227 227 IndexErrors are ignored.
228 228
229 229 Without args, fields() just split()'s the strings.
230 230 """
231 231 if len(fields) == 0:
232 232 return [el.split() for el in self]
233 233
234 234 res = SList()
235 235 for el in [f.split() for f in self]:
236 236 lineparts = []
237 237
238 238 for fd in fields:
239 239 try:
240 240 lineparts.append(el[fd])
241 241 except IndexError:
242 242 pass
243 243 if lineparts:
244 244 res.append(" ".join(lineparts))
245 245
246 246 return res
247 247
248 248 def sort(self,field= None, nums = False):
249 249 """ sort by specified fields (see fields())
250 250
251 251 Example::
252 252 a.sort(1, nums = True)
253 253
254 254 Sorts a by second field, in numerical order (so that 21 > 3)
255 255
256 256 """
257 257
258 258 #decorate, sort, undecorate
259 259 if field is not None:
260 260 dsu = [[SList([line]).fields(field), line] for line in self]
261 261 else:
262 262 dsu = [[line, line] for line in self]
263 263 if nums:
264 264 for i in range(len(dsu)):
265 265 numstr = "".join([ch for ch in dsu[i][0] if ch.isdigit()])
266 266 try:
267 267 n = int(numstr)
268 268 except ValueError:
269 269 n = 0;
270 270 dsu[i][0] = n
271 271
272 272
273 273 dsu.sort()
274 274 return SList([t[1] for t in dsu])
275 275
276 276
277 277 # FIXME: We need to reimplement type specific displayhook and then add this
278 278 # back as a custom printer. This should also be moved outside utils into the
279 279 # core.
280 280
281 281 # def print_slist(arg):
282 282 # """ Prettier (non-repr-like) and more informative printer for SList """
283 283 # print "SList (.p, .n, .l, .s, .grep(), .fields(), sort() available):"
284 284 # if hasattr(arg, 'hideonce') and arg.hideonce:
285 285 # arg.hideonce = False
286 286 # return
287 287 #
288 288 # nlprint(arg)
289 289 #
290 290 # print_slist = result_display.when_type(SList)(print_slist)
291 291
292 292
293 293 def esc_quotes(strng):
294 294 """Return the input string with single and double quotes escaped out"""
295 295
296 296 return strng.replace('"','\\"').replace("'","\\'")
297 297
298 298
299 299 def qw(words,flat=0,sep=None,maxsplit=-1):
300 300 """Similar to Perl's qw() operator, but with some more options.
301 301
302 302 qw(words,flat=0,sep=' ',maxsplit=-1) -> words.split(sep,maxsplit)
303 303
304 304 words can also be a list itself, and with flat=1, the output will be
305 305 recursively flattened.
306 306
307 307 Examples:
308 308
309 309 >>> qw('1 2')
310 310 ['1', '2']
311 311
312 312 >>> qw(['a b','1 2',['m n','p q']])
313 313 [['a', 'b'], ['1', '2'], [['m', 'n'], ['p', 'q']]]
314 314
315 315 >>> qw(['a b','1 2',['m n','p q']],flat=1)
316 316 ['a', 'b', '1', '2', 'm', 'n', 'p', 'q']
317 317 """
318 318
319 319 if isinstance(words, basestring):
320 320 return [word.strip() for word in words.split(sep,maxsplit)
321 321 if word and not word.isspace() ]
322 322 if flat:
323 323 return flatten(map(qw,words,[1]*len(words)))
324 324 return map(qw,words)
325 325
326 326
327 327 def qwflat(words,sep=None,maxsplit=-1):
328 328 """Calls qw(words) in flat mode. It's just a convenient shorthand."""
329 329 return qw(words,1,sep,maxsplit)
330 330
331 331
332 332 def qw_lol(indata):
333 333 """qw_lol('a b') -> [['a','b']],
334 334 otherwise it's just a call to qw().
335 335
336 336 We need this to make sure the modules_some keys *always* end up as a
337 337 list of lists."""
338 338
339 339 if isinstance(indata, basestring):
340 340 return [qw(indata)]
341 341 else:
342 342 return qw(indata)
343 343
344 344
345 345 def grep(pat,list,case=1):
346 346 """Simple minded grep-like function.
347 347 grep(pat,list) returns occurrences of pat in list, None on failure.
348 348
349 349 It only does simple string matching, with no support for regexps. Use the
350 350 option case=0 for case-insensitive matching."""
351 351
352 352 # This is pretty crude. At least it should implement copying only references
353 353 # to the original data in case it's big. Now it copies the data for output.
354 354 out=[]
355 355 if case:
356 356 for term in list:
357 357 if term.find(pat)>-1: out.append(term)
358 358 else:
359 359 lpat=pat.lower()
360 360 for term in list:
361 361 if term.lower().find(lpat)>-1: out.append(term)
362 362
363 363 if len(out): return out
364 364 else: return None
365 365
366 366
367 367 def dgrep(pat,*opts):
368 368 """Return grep() on dir()+dir(__builtins__).
369 369
370 370 A very common use of grep() when working interactively."""
371 371
372 372 return grep(pat,dir(__main__)+dir(__main__.__builtins__),*opts)
373 373
374 374
375 375 def idgrep(pat):
376 376 """Case-insensitive dgrep()"""
377 377
378 378 return dgrep(pat,0)
379 379
380 380
381 381 def igrep(pat,list):
382 382 """Synonym for case-insensitive grep."""
383 383
384 384 return grep(pat,list,case=0)
385 385
386 386
387 387 def indent(instr,nspaces=4, ntabs=0, flatten=False):
388 388 """Indent a string a given number of spaces or tabstops.
389 389
390 390 indent(str,nspaces=4,ntabs=0) -> indent str by ntabs+nspaces.
391 391
392 392 Parameters
393 393 ----------
394 394
395 395 instr : basestring
396 396 The string to be indented.
397 397 nspaces : int (default: 4)
398 398 The number of spaces to be indented.
399 399 ntabs : int (default: 0)
400 400 The number of tabs to be indented.
401 401 flatten : bool (default: False)
402 402 Whether to scrub existing indentation. If True, all lines will be
403 403 aligned to the same indentation. If False, existing indentation will
404 404 be strictly increased.
405 405
406 406 Returns
407 407 -------
408 408
409 409 str|unicode : string indented by ntabs and nspaces.
410 410
411 411 """
412 412 if instr is None:
413 413 return
414 414 ind = '\t'*ntabs+' '*nspaces
415 415 if flatten:
416 416 pat = re.compile(r'^\s*', re.MULTILINE)
417 417 else:
418 418 pat = re.compile(r'^', re.MULTILINE)
419 419 outstr = re.sub(pat, ind, instr)
420 420 if outstr.endswith(os.linesep+ind):
421 421 return outstr[:-len(ind)]
422 422 else:
423 423 return outstr
424 424
425 425 def native_line_ends(filename,backup=1):
426 426 """Convert (in-place) a file to line-ends native to the current OS.
427 427
428 428 If the optional backup argument is given as false, no backup of the
429 429 original file is left. """
430 430
431 431 backup_suffixes = {'posix':'~','dos':'.bak','nt':'.bak','mac':'.bak'}
432 432
433 433 bak_filename = filename + backup_suffixes[os.name]
434 434
435 435 original = open(filename).read()
436 436 shutil.copy2(filename,bak_filename)
437 437 try:
438 438 new = open(filename,'wb')
439 439 new.write(os.linesep.join(original.splitlines()))
440 440 new.write(os.linesep) # ALWAYS put an eol at the end of the file
441 441 new.close()
442 442 except:
443 443 os.rename(bak_filename,filename)
444 444 if not backup:
445 445 try:
446 446 os.remove(bak_filename)
447 447 except:
448 448 pass
449 449
450 450
451 451 def list_strings(arg):
452 452 """Always return a list of strings, given a string or list of strings
453 453 as input.
454 454
455 455 :Examples:
456 456
457 457 In [7]: list_strings('A single string')
458 458 Out[7]: ['A single string']
459 459
460 460 In [8]: list_strings(['A single string in a list'])
461 461 Out[8]: ['A single string in a list']
462 462
463 463 In [9]: list_strings(['A','list','of','strings'])
464 464 Out[9]: ['A', 'list', 'of', 'strings']
465 465 """
466 466
467 467 if isinstance(arg,basestring): return [arg]
468 468 else: return arg
469 469
470 470
471 471 def marquee(txt='',width=78,mark='*'):
472 472 """Return the input string centered in a 'marquee'.
473 473
474 474 :Examples:
475 475
476 476 In [16]: marquee('A test',40)
477 477 Out[16]: '**************** A test ****************'
478 478
479 479 In [17]: marquee('A test',40,'-')
480 480 Out[17]: '---------------- A test ----------------'
481 481
482 482 In [18]: marquee('A test',40,' ')
483 483 Out[18]: ' A test '
484 484
485 485 """
486 486 if not txt:
487 487 return (mark*width)[:width]
488 488 nmark = (width-len(txt)-2)//len(mark)//2
489 489 if nmark < 0: nmark =0
490 490 marks = mark*nmark
491 491 return '%s %s %s' % (marks,txt,marks)
492 492
493 493
494 494 ini_spaces_re = re.compile(r'^(\s+)')
495 495
496 496 def num_ini_spaces(strng):
497 497 """Return the number of initial spaces in a string"""
498 498
499 499 ini_spaces = ini_spaces_re.match(strng)
500 500 if ini_spaces:
501 501 return ini_spaces.end()
502 502 else:
503 503 return 0
504 504
505 505
506 506 def format_screen(strng):
507 507 """Format a string for screen printing.
508 508
509 509 This removes some latex-type format codes."""
510 510 # Paragraph continue
511 511 par_re = re.compile(r'\\$',re.MULTILINE)
512 512 strng = par_re.sub('',strng)
513 513 return strng
514 514
515 515 def dedent(text):
516 516 """Equivalent of textwrap.dedent that ignores unindented first line.
517 517
518 518 This means it will still dedent strings like:
519 519 '''foo
520 520 is a bar
521 521 '''
522 522
523 523 For use in wrap_paragraphs.
524 524 """
525 525
526 526 if text.startswith('\n'):
527 527 # text starts with blank line, don't ignore the first line
528 528 return textwrap.dedent(text)
529 529
530 530 # split first line
531 531 splits = text.split('\n',1)
532 532 if len(splits) == 1:
533 533 # only one line
534 534 return textwrap.dedent(text)
535 535
536 536 first, rest = splits
537 537 # dedent everything but the first line
538 538 rest = textwrap.dedent(rest)
539 539 return '\n'.join([first, rest])
540 540
541 541 def wrap_paragraphs(text, ncols=80):
542 542 """Wrap multiple paragraphs to fit a specified width.
543 543
544 544 This is equivalent to textwrap.wrap, but with support for multiple
545 545 paragraphs, as separated by empty lines.
546 546
547 547 Returns
548 548 -------
549 549
550 550 list of complete paragraphs, wrapped to fill `ncols` columns.
551 551 """
552 552 paragraph_re = re.compile(r'\n(\s*\n)+', re.MULTILINE)
553 553 text = dedent(text).strip()
554 554 paragraphs = paragraph_re.split(text)[::2] # every other entry is space
555 555 out_ps = []
556 556 indent_re = re.compile(r'\n\s+', re.MULTILINE)
557 557 for p in paragraphs:
558 558 # presume indentation that survives dedent is meaningful formatting,
559 559 # so don't fill unless text is flush.
560 560 if indent_re.search(p) is None:
561 561 # wrap paragraph
562 562 p = textwrap.fill(p, ncols)
563 563 out_ps.append(p)
564 564 return out_ps
565 565
566 566
567 567 class EvalFormatter(Formatter):
568 568 """A String Formatter that allows evaluation of simple expressions.
569 569
570 570 Note that this version interprets a : as specifying a format string (as per
571 571 standard string formatting), so if slicing is required, you must explicitly
572 572 create a slice.
573 573
574 574 This is to be used in templating cases, such as the parallel batch
575 575 script templates, where simple arithmetic on arguments is useful.
576 576
577 577 Examples
578 578 --------
579 579
580 580 In [1]: f = EvalFormatter()
581 581 In [2]: f.format('{n//4}', n=8)
582 582 Out [2]: '2'
583 583
584 584 In [3]: f.format("{greeting[slice(2,4)]}", greeting="Hello")
585 585 Out [3]: 'll'
586 586 """
587 587 def get_field(self, name, args, kwargs):
588 588 v = eval(name, kwargs)
589 589 return v, name
590 590
591 591 @skip_doctest_py3
592 592 class FullEvalFormatter(Formatter):
593 593 """A String Formatter that allows evaluation of simple expressions.
594 594
595 595 Any time a format key is not found in the kwargs,
596 596 it will be tried as an expression in the kwargs namespace.
597 597
598 598 Note that this version allows slicing using [1:2], so you cannot specify
599 599 a format string. Use :class:`EvalFormatter` to permit format strings.
600 600
601 601 Examples
602 602 --------
603 603
604 604 In [1]: f = FullEvalFormatter()
605 605 In [2]: f.format('{n//4}', n=8)
606 606 Out[2]: u'2'
607 607
608 608 In [3]: f.format('{list(range(5))[2:4]}')
609 609 Out[3]: u'[2, 3]'
610 610
611 611 In [4]: f.format('{3*2}')
612 612 Out[4]: u'6'
613 613 """
614 614 # copied from Formatter._vformat with minor changes to allow eval
615 615 # and replace the format_spec code with slicing
616 616 def _vformat(self, format_string, args, kwargs, used_args, recursion_depth):
617 617 if recursion_depth < 0:
618 618 raise ValueError('Max string recursion exceeded')
619 619 result = []
620 620 for literal_text, field_name, format_spec, conversion in \
621 621 self.parse(format_string):
622 622
623 623 # output the literal text
624 624 if literal_text:
625 625 result.append(literal_text)
626 626
627 627 # if there's a field, output it
628 628 if field_name is not None:
629 629 # this is some markup, find the object and do
630 630 # the formatting
631 631
632 632 if format_spec:
633 633 # override format spec, to allow slicing:
634 634 field_name = ':'.join([field_name, format_spec])
635 635
636 636 # eval the contents of the field for the object
637 637 # to be formatted
638 638 obj = eval(field_name, kwargs)
639 639
640 640 # do any conversion on the resulting object
641 641 obj = self.convert_field(obj, conversion)
642 642
643 643 # format the object and append to the result
644 644 result.append(self.format_field(obj, ''))
645 645
646 646 return u''.join(py3compat.cast_unicode(s) for s in result)
647 647
648 648 @skip_doctest_py3
649 649 class DollarFormatter(FullEvalFormatter):
650 650 """Formatter allowing Itpl style $foo replacement, for names and attribute
651 651 access only. Standard {foo} replacement also works, and allows full
652 652 evaluation of its arguments.
653 653
654 654 Examples
655 655 --------
656 656 In [1]: f = DollarFormatter()
657 657 In [2]: f.format('{n//4}', n=8)
658 658 Out[2]: u'2'
659 659
660 660 In [3]: f.format('23 * 76 is $result', result=23*76)
661 661 Out[3]: u'23 * 76 is 1748'
662 662
663 663 In [4]: f.format('$a or {b}', a=1, b=2)
664 664 Out[4]: u'1 or 2'
665 665 """
666 666 _dollar_pattern = re.compile("(.*?)\$(\$?[\w\.]+)")
667 667 def parse(self, fmt_string):
668 668 for literal_txt, field_name, format_spec, conversion \
669 669 in Formatter.parse(self, fmt_string):
670 670
671 671 # Find $foo patterns in the literal text.
672 672 continue_from = 0
673 673 txt = ""
674 674 for m in self._dollar_pattern.finditer(literal_txt):
675 675 new_txt, new_field = m.group(1,2)
676 676 # $$foo --> $foo
677 677 if new_field.startswith("$"):
678 678 txt += new_txt + new_field
679 679 else:
680 680 yield (txt + new_txt, new_field, "", None)
681 681 txt = ""
682 682 continue_from = m.end()
683 683
684 684 # Re-yield the {foo} style pattern
685 685 yield (txt + literal_txt[continue_from:], field_name, format_spec, conversion)
686 686
687 687
688 688 def columnize(items, separator=' ', displaywidth=80):
689 689 """ Transform a list of strings into a single string with columns.
690 690
691 691 Parameters
692 692 ----------
693 693 items : sequence of strings
694 694 The strings to process.
695 695
696 696 separator : str, optional [default is two spaces]
697 697 The string that separates columns.
698 698
699 699 displaywidth : int, optional [default is 80]
700 700 Width of the display in number of characters.
701 701
702 702 Returns
703 703 -------
704 704 The formatted string.
705 705 """
706 706 # Note: this code is adapted from columnize 0.3.2.
707 707 # See http://code.google.com/p/pycolumnize/
708 708
709 709 # Some degenerate cases.
710 710 size = len(items)
711 711 if size == 0:
712 712 return '\n'
713 713 elif size == 1:
714 714 return '%s\n' % items[0]
715 715
716 716 # Special case: if any item is longer than the maximum width, there's no
717 717 # point in triggering the logic below...
718 718 item_len = map(len, items) # save these, we can reuse them below
719 719 longest = max(item_len)
720 720 if longest >= displaywidth:
721 721 return '\n'.join(items+[''])
722 722
723 723 # Try every row count from 1 upwards
724 724 array_index = lambda nrows, row, col: nrows*col + row
725 725 for nrows in range(1, size):
726 726 ncols = (size + nrows - 1) // nrows
727 727 colwidths = []
728 728 totwidth = -len(separator)
729 729 for col in range(ncols):
730 730 # Get max column width for this column
731 731 colwidth = 0
732 732 for row in range(nrows):
733 733 i = array_index(nrows, row, col)
734 734 if i >= size: break
735 735 x, len_x = items[i], item_len[i]
736 736 colwidth = max(colwidth, len_x)
737 737 colwidths.append(colwidth)
738 738 totwidth += colwidth + len(separator)
739 739 if totwidth > displaywidth:
740 740 break
741 741 if totwidth <= displaywidth:
742 742 break
743 743
744 744 # The smallest number of rows computed and the max widths for each
745 745 # column has been obtained. Now we just have to format each of the rows.
746 746 string = ''
747 747 for row in range(nrows):
748 748 texts = []
749 749 for col in range(ncols):
750 750 i = row + nrows*col
751 751 if i >= size:
752 752 texts.append('')
753 753 else:
754 754 texts.append(items[i])
755 755 while texts and not texts[-1]:
756 756 del texts[-1]
757 757 for col in range(len(texts)):
758 758 texts[col] = texts[col].ljust(colwidths[col])
759 759 string += '%s\n' % separator.join(texts)
760 760 return string
General Comments 0
You need to be logged in to leave comments. Login now