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