##// END OF EJS Templates
Switch some references to input_splitter to input_transformer_manager
Thomas Kluyver -
Show More
@@ -1,525 +1,525 b''
1 from codeop import compile_command
1 from codeop import compile_command
2 import re
2 import re
3 from typing import List, Tuple
3 from typing import List, Tuple
4 from IPython.utils import tokenize2
4 from IPython.utils import tokenize2
5 from IPython.utils.tokenutil import generate_tokens
5 from IPython.utils.tokenutil import generate_tokens
6
6
7 _indent_re = re.compile(r'^[ \t]+')
7 _indent_re = re.compile(r'^[ \t]+')
8
8
9 def leading_indent(lines):
9 def leading_indent(lines):
10 """Remove leading indentation.
10 """Remove leading indentation.
11
11
12 If the first line starts with a spaces or tabs, the same whitespace will be
12 If the first line starts with a spaces or tabs, the same whitespace will be
13 removed from each following line.
13 removed from each following line.
14 """
14 """
15 m = _indent_re.match(lines[0])
15 m = _indent_re.match(lines[0])
16 if not m:
16 if not m:
17 return lines
17 return lines
18 space = m.group(0)
18 space = m.group(0)
19 n = len(space)
19 n = len(space)
20 return [l[n:] if l.startswith(space) else l
20 return [l[n:] if l.startswith(space) else l
21 for l in lines]
21 for l in lines]
22
22
23 class PromptStripper:
23 class PromptStripper:
24 """Remove matching input prompts from a block of input.
24 """Remove matching input prompts from a block of input.
25
25
26 Parameters
26 Parameters
27 ----------
27 ----------
28 prompt_re : regular expression
28 prompt_re : regular expression
29 A regular expression matching any input prompt (including continuation)
29 A regular expression matching any input prompt (including continuation)
30 initial_re : regular expression, optional
30 initial_re : regular expression, optional
31 A regular expression matching only the initial prompt, but not continuation.
31 A regular expression matching only the initial prompt, but not continuation.
32 If no initial expression is given, prompt_re will be used everywhere.
32 If no initial expression is given, prompt_re will be used everywhere.
33 Used mainly for plain Python prompts, where the continuation prompt
33 Used mainly for plain Python prompts, where the continuation prompt
34 ``...`` is a valid Python expression in Python 3, so shouldn't be stripped.
34 ``...`` is a valid Python expression in Python 3, so shouldn't be stripped.
35
35
36 If initial_re and prompt_re differ,
36 If initial_re and prompt_re differ,
37 only initial_re will be tested against the first line.
37 only initial_re will be tested against the first line.
38 If any prompt is found on the first two lines,
38 If any prompt is found on the first two lines,
39 prompts will be stripped from the rest of the block.
39 prompts will be stripped from the rest of the block.
40 """
40 """
41 def __init__(self, prompt_re, initial_re=None):
41 def __init__(self, prompt_re, initial_re=None):
42 self.prompt_re = prompt_re
42 self.prompt_re = prompt_re
43 self.initial_re = initial_re or prompt_re
43 self.initial_re = initial_re or prompt_re
44
44
45 def _strip(self, lines):
45 def _strip(self, lines):
46 return [self.prompt_re.sub('', l, count=1) for l in lines]
46 return [self.prompt_re.sub('', l, count=1) for l in lines]
47
47
48 def __call__(self, lines):
48 def __call__(self, lines):
49 if self.initial_re.match(lines[0]) or \
49 if self.initial_re.match(lines[0]) or \
50 (len(lines) > 1 and self.prompt_re.match(lines[1])):
50 (len(lines) > 1 and self.prompt_re.match(lines[1])):
51 return self._strip(lines)
51 return self._strip(lines)
52 return lines
52 return lines
53
53
54 classic_prompt = PromptStripper(
54 classic_prompt = PromptStripper(
55 prompt_re=re.compile(r'^(>>>|\.\.\.)( |$)'),
55 prompt_re=re.compile(r'^(>>>|\.\.\.)( |$)'),
56 initial_re=re.compile(r'^>>>( |$)')
56 initial_re=re.compile(r'^>>>( |$)')
57 )
57 )
58
58
59 ipython_prompt = PromptStripper(re.compile(r'^(In \[\d+\]: |\s*\.{3,}: ?)'))
59 ipython_prompt = PromptStripper(re.compile(r'^(In \[\d+\]: |\s*\.{3,}: ?)'))
60
60
61 def cell_magic(lines):
61 def cell_magic(lines):
62 if not lines[0].startswith('%%'):
62 if not lines[0].startswith('%%'):
63 return lines
63 return lines
64 if re.match('%%\w+\?', lines[0]):
64 if re.match('%%\w+\?', lines[0]):
65 # This case will be handled by help_end
65 # This case will be handled by help_end
66 return lines
66 return lines
67 magic_name, _, first_line = lines[0][2:-1].partition(' ')
67 magic_name, _, first_line = lines[0][2:-1].partition(' ')
68 body = ''.join(lines[1:])
68 body = ''.join(lines[1:])
69 return ['get_ipython().run_cell_magic(%r, %r, %r)\n'
69 return ['get_ipython().run_cell_magic(%r, %r, %r)\n'
70 % (magic_name, first_line, body)]
70 % (magic_name, first_line, body)]
71
71
72 # -----
72 # -----
73
73
74 def _find_assign_op(token_line):
74 def _find_assign_op(token_line):
75 # Find the first assignment in the line ('=' not inside brackets)
75 # Find the first assignment in the line ('=' not inside brackets)
76 # We don't try to support multiple special assignment (a = b = %foo)
76 # We don't try to support multiple special assignment (a = b = %foo)
77 paren_level = 0
77 paren_level = 0
78 for i, ti in enumerate(token_line):
78 for i, ti in enumerate(token_line):
79 s = ti.string
79 s = ti.string
80 if s == '=' and paren_level == 0:
80 if s == '=' and paren_level == 0:
81 return i
81 return i
82 if s in '([{':
82 if s in '([{':
83 paren_level += 1
83 paren_level += 1
84 elif s in ')]}':
84 elif s in ')]}':
85 paren_level -= 1
85 paren_level -= 1
86
86
87 def find_end_of_continued_line(lines, start_line: int):
87 def find_end_of_continued_line(lines, start_line: int):
88 """Find the last line of a line explicitly extended using backslashes.
88 """Find the last line of a line explicitly extended using backslashes.
89
89
90 Uses 0-indexed line numbers.
90 Uses 0-indexed line numbers.
91 """
91 """
92 end_line = start_line
92 end_line = start_line
93 while lines[end_line].endswith('\\\n'):
93 while lines[end_line].endswith('\\\n'):
94 end_line += 1
94 end_line += 1
95 if end_line >= len(lines):
95 if end_line >= len(lines):
96 break
96 break
97 return end_line
97 return end_line
98
98
99 def assemble_continued_line(lines, start: Tuple[int, int], end_line: int):
99 def assemble_continued_line(lines, start: Tuple[int, int], end_line: int):
100 """Assemble pieces of a continued line into a single line.
100 """Assemble pieces of a continued line into a single line.
101
101
102 Uses 0-indexed line numbers. *start* is (lineno, colno).
102 Uses 0-indexed line numbers. *start* is (lineno, colno).
103 """
103 """
104 parts = [lines[start[0]][start[1]:]] + lines[start[0]+1:end_line+1]
104 parts = [lines[start[0]][start[1]:]] + lines[start[0]+1:end_line+1]
105 return ' '.join([p[:-2] for p in parts[:-1]] # Strip backslash+newline
105 return ' '.join([p[:-2] for p in parts[:-1]] # Strip backslash+newline
106 + [parts[-1][:-1]]) # Strip newline from last line
106 + [parts[-1][:-1]]) # Strip newline from last line
107
107
108 class TokenTransformBase:
108 class TokenTransformBase:
109 # Lower numbers -> higher priority (for matches in the same location)
109 # Lower numbers -> higher priority (for matches in the same location)
110 priority = 10
110 priority = 10
111
111
112 def sortby(self):
112 def sortby(self):
113 return self.start_line, self.start_col, self.priority
113 return self.start_line, self.start_col, self.priority
114
114
115 def __init__(self, start):
115 def __init__(self, start):
116 self.start_line = start[0] - 1 # Shift from 1-index to 0-index
116 self.start_line = start[0] - 1 # Shift from 1-index to 0-index
117 self.start_col = start[1]
117 self.start_col = start[1]
118
118
119 def transform(self, lines: List[str]):
119 def transform(self, lines: List[str]):
120 raise NotImplementedError
120 raise NotImplementedError
121
121
122 class MagicAssign(TokenTransformBase):
122 class MagicAssign(TokenTransformBase):
123 @classmethod
123 @classmethod
124 def find(cls, tokens_by_line):
124 def find(cls, tokens_by_line):
125 """Find the first magic assignment (a = %foo) in the cell.
125 """Find the first magic assignment (a = %foo) in the cell.
126
126
127 Returns (line, column) of the % if found, or None. *line* is 1-indexed.
127 Returns (line, column) of the % if found, or None. *line* is 1-indexed.
128 """
128 """
129 for line in tokens_by_line:
129 for line in tokens_by_line:
130 assign_ix = _find_assign_op(line)
130 assign_ix = _find_assign_op(line)
131 if (assign_ix is not None) \
131 if (assign_ix is not None) \
132 and (len(line) >= assign_ix + 2) \
132 and (len(line) >= assign_ix + 2) \
133 and (line[assign_ix+1].string == '%') \
133 and (line[assign_ix+1].string == '%') \
134 and (line[assign_ix+2].type == tokenize2.NAME):
134 and (line[assign_ix+2].type == tokenize2.NAME):
135 return cls(line[assign_ix+1].start)
135 return cls(line[assign_ix+1].start)
136
136
137 def transform(self, lines: List[str]):
137 def transform(self, lines: List[str]):
138 """Transform a magic assignment found by find
138 """Transform a magic assignment found by find
139 """
139 """
140 start_line, start_col = self.start_line, self.start_col
140 start_line, start_col = self.start_line, self.start_col
141 lhs = lines[start_line][:start_col]
141 lhs = lines[start_line][:start_col]
142 end_line = find_end_of_continued_line(lines, start_line)
142 end_line = find_end_of_continued_line(lines, start_line)
143 rhs = assemble_continued_line(lines, (start_line, start_col), end_line)
143 rhs = assemble_continued_line(lines, (start_line, start_col), end_line)
144 assert rhs.startswith('%'), rhs
144 assert rhs.startswith('%'), rhs
145 magic_name, _, args = rhs[1:].partition(' ')
145 magic_name, _, args = rhs[1:].partition(' ')
146
146
147 lines_before = lines[:start_line]
147 lines_before = lines[:start_line]
148 call = "get_ipython().run_line_magic({!r}, {!r})".format(magic_name, args)
148 call = "get_ipython().run_line_magic({!r}, {!r})".format(magic_name, args)
149 new_line = lhs + call + '\n'
149 new_line = lhs + call + '\n'
150 lines_after = lines[end_line+1:]
150 lines_after = lines[end_line+1:]
151
151
152 return lines_before + [new_line] + lines_after
152 return lines_before + [new_line] + lines_after
153
153
154
154
155 class SystemAssign(TokenTransformBase):
155 class SystemAssign(TokenTransformBase):
156 @classmethod
156 @classmethod
157 def find(cls, tokens_by_line):
157 def find(cls, tokens_by_line):
158 """Find the first system assignment (a = !foo) in the cell.
158 """Find the first system assignment (a = !foo) in the cell.
159
159
160 Returns (line, column) of the ! if found, or None. *line* is 1-indexed.
160 Returns (line, column) of the ! if found, or None. *line* is 1-indexed.
161 """
161 """
162 for line in tokens_by_line:
162 for line in tokens_by_line:
163 assign_ix = _find_assign_op(line)
163 assign_ix = _find_assign_op(line)
164 if (assign_ix is not None) \
164 if (assign_ix is not None) \
165 and (len(line) >= assign_ix + 2) \
165 and (len(line) >= assign_ix + 2) \
166 and (line[assign_ix + 1].type == tokenize2.ERRORTOKEN):
166 and (line[assign_ix + 1].type == tokenize2.ERRORTOKEN):
167 ix = assign_ix + 1
167 ix = assign_ix + 1
168
168
169 while ix < len(line) and line[ix].type == tokenize2.ERRORTOKEN:
169 while ix < len(line) and line[ix].type == tokenize2.ERRORTOKEN:
170 if line[ix].string == '!':
170 if line[ix].string == '!':
171 return cls(line[ix].start)
171 return cls(line[ix].start)
172 elif not line[ix].string.isspace():
172 elif not line[ix].string.isspace():
173 break
173 break
174 ix += 1
174 ix += 1
175
175
176 def transform(self, lines: List[str]):
176 def transform(self, lines: List[str]):
177 """Transform a system assignment found by find
177 """Transform a system assignment found by find
178 """
178 """
179 start_line, start_col = self.start_line, self.start_col
179 start_line, start_col = self.start_line, self.start_col
180
180
181 lhs = lines[start_line][:start_col]
181 lhs = lines[start_line][:start_col]
182 end_line = find_end_of_continued_line(lines, start_line)
182 end_line = find_end_of_continued_line(lines, start_line)
183 rhs = assemble_continued_line(lines, (start_line, start_col), end_line)
183 rhs = assemble_continued_line(lines, (start_line, start_col), end_line)
184 assert rhs.startswith('!'), rhs
184 assert rhs.startswith('!'), rhs
185 cmd = rhs[1:]
185 cmd = rhs[1:]
186
186
187 lines_before = lines[:start_line]
187 lines_before = lines[:start_line]
188 call = "get_ipython().getoutput({!r})".format(cmd)
188 call = "get_ipython().getoutput({!r})".format(cmd)
189 new_line = lhs + call + '\n'
189 new_line = lhs + call + '\n'
190 lines_after = lines[end_line + 1:]
190 lines_after = lines[end_line + 1:]
191
191
192 return lines_before + [new_line] + lines_after
192 return lines_before + [new_line] + lines_after
193
193
194 # The escape sequences that define the syntax transformations IPython will
194 # The escape sequences that define the syntax transformations IPython will
195 # apply to user input. These can NOT be just changed here: many regular
195 # apply to user input. These can NOT be just changed here: many regular
196 # expressions and other parts of the code may use their hardcoded values, and
196 # expressions and other parts of the code may use their hardcoded values, and
197 # for all intents and purposes they constitute the 'IPython syntax', so they
197 # for all intents and purposes they constitute the 'IPython syntax', so they
198 # should be considered fixed.
198 # should be considered fixed.
199
199
200 ESC_SHELL = '!' # Send line to underlying system shell
200 ESC_SHELL = '!' # Send line to underlying system shell
201 ESC_SH_CAP = '!!' # Send line to system shell and capture output
201 ESC_SH_CAP = '!!' # Send line to system shell and capture output
202 ESC_HELP = '?' # Find information about object
202 ESC_HELP = '?' # Find information about object
203 ESC_HELP2 = '??' # Find extra-detailed information about object
203 ESC_HELP2 = '??' # Find extra-detailed information about object
204 ESC_MAGIC = '%' # Call magic function
204 ESC_MAGIC = '%' # Call magic function
205 ESC_MAGIC2 = '%%' # Call cell-magic function
205 ESC_MAGIC2 = '%%' # Call cell-magic function
206 ESC_QUOTE = ',' # Split args on whitespace, quote each as string and call
206 ESC_QUOTE = ',' # Split args on whitespace, quote each as string and call
207 ESC_QUOTE2 = ';' # Quote all args as a single string, call
207 ESC_QUOTE2 = ';' # Quote all args as a single string, call
208 ESC_PAREN = '/' # Call first argument with rest of line as arguments
208 ESC_PAREN = '/' # Call first argument with rest of line as arguments
209
209
210 ESCAPE_SINGLES = {'!', '?', '%', ',', ';', '/'}
210 ESCAPE_SINGLES = {'!', '?', '%', ',', ';', '/'}
211 ESCAPE_DOUBLES = {'!!', '??'} # %% (cell magic) is handled separately
211 ESCAPE_DOUBLES = {'!!', '??'} # %% (cell magic) is handled separately
212
212
213 def _make_help_call(target, esc, next_input=None):
213 def _make_help_call(target, esc, next_input=None):
214 """Prepares a pinfo(2)/psearch call from a target name and the escape
214 """Prepares a pinfo(2)/psearch call from a target name and the escape
215 (i.e. ? or ??)"""
215 (i.e. ? or ??)"""
216 method = 'pinfo2' if esc == '??' \
216 method = 'pinfo2' if esc == '??' \
217 else 'psearch' if '*' in target \
217 else 'psearch' if '*' in target \
218 else 'pinfo'
218 else 'pinfo'
219 arg = " ".join([method, target])
219 arg = " ".join([method, target])
220 #Prepare arguments for get_ipython().run_line_magic(magic_name, magic_args)
220 #Prepare arguments for get_ipython().run_line_magic(magic_name, magic_args)
221 t_magic_name, _, t_magic_arg_s = arg.partition(' ')
221 t_magic_name, _, t_magic_arg_s = arg.partition(' ')
222 t_magic_name = t_magic_name.lstrip(ESC_MAGIC)
222 t_magic_name = t_magic_name.lstrip(ESC_MAGIC)
223 if next_input is None:
223 if next_input is None:
224 return 'get_ipython().run_line_magic(%r, %r)' % (t_magic_name, t_magic_arg_s)
224 return 'get_ipython().run_line_magic(%r, %r)' % (t_magic_name, t_magic_arg_s)
225 else:
225 else:
226 return 'get_ipython().set_next_input(%r);get_ipython().run_line_magic(%r, %r)' % \
226 return 'get_ipython().set_next_input(%r);get_ipython().run_line_magic(%r, %r)' % \
227 (next_input, t_magic_name, t_magic_arg_s)
227 (next_input, t_magic_name, t_magic_arg_s)
228
228
229 def _tr_help(content):
229 def _tr_help(content):
230 "Translate lines escaped with: ?"
230 "Translate lines escaped with: ?"
231 # A naked help line should just fire the intro help screen
231 # A naked help line should just fire the intro help screen
232 if not content:
232 if not content:
233 return 'get_ipython().show_usage()'
233 return 'get_ipython().show_usage()'
234
234
235 return _make_help_call(content, '?')
235 return _make_help_call(content, '?')
236
236
237 def _tr_help2(content):
237 def _tr_help2(content):
238 "Translate lines escaped with: ??"
238 "Translate lines escaped with: ??"
239 # A naked help line should just fire the intro help screen
239 # A naked help line should just fire the intro help screen
240 if not content:
240 if not content:
241 return 'get_ipython().show_usage()'
241 return 'get_ipython().show_usage()'
242
242
243 return _make_help_call(content, '??')
243 return _make_help_call(content, '??')
244
244
245 def _tr_magic(content):
245 def _tr_magic(content):
246 "Translate lines escaped with: %"
246 "Translate lines escaped with: %"
247 name, _, args = content.partition(' ')
247 name, _, args = content.partition(' ')
248 return 'get_ipython().run_line_magic(%r, %r)' % (name, args)
248 return 'get_ipython().run_line_magic(%r, %r)' % (name, args)
249
249
250 def _tr_quote(content):
250 def _tr_quote(content):
251 "Translate lines escaped with: ,"
251 "Translate lines escaped with: ,"
252 name, _, args = content.partition(' ')
252 name, _, args = content.partition(' ')
253 return '%s("%s")' % (name, '", "'.join(args.split()) )
253 return '%s("%s")' % (name, '", "'.join(args.split()) )
254
254
255 def _tr_quote2(content):
255 def _tr_quote2(content):
256 "Translate lines escaped with: ;"
256 "Translate lines escaped with: ;"
257 name, _, args = content.partition(' ')
257 name, _, args = content.partition(' ')
258 return '%s("%s")' % (name, args)
258 return '%s("%s")' % (name, args)
259
259
260 def _tr_paren(content):
260 def _tr_paren(content):
261 "Translate lines escaped with: /"
261 "Translate lines escaped with: /"
262 name, _, args = content.partition(' ')
262 name, _, args = content.partition(' ')
263 return '%s(%s)' % (name, ", ".join(args.split()))
263 return '%s(%s)' % (name, ", ".join(args.split()))
264
264
265 tr = { ESC_SHELL : 'get_ipython().system({!r})'.format,
265 tr = { ESC_SHELL : 'get_ipython().system({!r})'.format,
266 ESC_SH_CAP : 'get_ipython().getoutput({!r})'.format,
266 ESC_SH_CAP : 'get_ipython().getoutput({!r})'.format,
267 ESC_HELP : _tr_help,
267 ESC_HELP : _tr_help,
268 ESC_HELP2 : _tr_help2,
268 ESC_HELP2 : _tr_help2,
269 ESC_MAGIC : _tr_magic,
269 ESC_MAGIC : _tr_magic,
270 ESC_QUOTE : _tr_quote,
270 ESC_QUOTE : _tr_quote,
271 ESC_QUOTE2 : _tr_quote2,
271 ESC_QUOTE2 : _tr_quote2,
272 ESC_PAREN : _tr_paren }
272 ESC_PAREN : _tr_paren }
273
273
274 class EscapedCommand(TokenTransformBase):
274 class EscapedCommand(TokenTransformBase):
275 @classmethod
275 @classmethod
276 def find(cls, tokens_by_line):
276 def find(cls, tokens_by_line):
277 """Find the first escaped command (%foo, !foo, etc.) in the cell.
277 """Find the first escaped command (%foo, !foo, etc.) in the cell.
278
278
279 Returns (line, column) of the escape if found, or None. *line* is 1-indexed.
279 Returns (line, column) of the escape if found, or None. *line* is 1-indexed.
280 """
280 """
281 for line in tokens_by_line:
281 for line in tokens_by_line:
282 ix = 0
282 ix = 0
283 while line[ix].type in {tokenize2.INDENT, tokenize2.DEDENT}:
283 while line[ix].type in {tokenize2.INDENT, tokenize2.DEDENT}:
284 ix += 1
284 ix += 1
285 if line[ix].string in ESCAPE_SINGLES:
285 if line[ix].string in ESCAPE_SINGLES:
286 return cls(line[ix].start)
286 return cls(line[ix].start)
287
287
288 def transform(self, lines):
288 def transform(self, lines):
289 start_line, start_col = self.start_line, self.start_col
289 start_line, start_col = self.start_line, self.start_col
290
290
291 indent = lines[start_line][:start_col]
291 indent = lines[start_line][:start_col]
292 end_line = find_end_of_continued_line(lines, start_line)
292 end_line = find_end_of_continued_line(lines, start_line)
293 line = assemble_continued_line(lines, (start_line, start_col), end_line)
293 line = assemble_continued_line(lines, (start_line, start_col), end_line)
294
294
295 if line[:2] in ESCAPE_DOUBLES:
295 if line[:2] in ESCAPE_DOUBLES:
296 escape, content = line[:2], line[2:]
296 escape, content = line[:2], line[2:]
297 else:
297 else:
298 escape, content = line[:1], line[1:]
298 escape, content = line[:1], line[1:]
299 call = tr[escape](content)
299 call = tr[escape](content)
300
300
301 lines_before = lines[:start_line]
301 lines_before = lines[:start_line]
302 new_line = indent + call + '\n'
302 new_line = indent + call + '\n'
303 lines_after = lines[end_line + 1:]
303 lines_after = lines[end_line + 1:]
304
304
305 return lines_before + [new_line] + lines_after
305 return lines_before + [new_line] + lines_after
306
306
307 _help_end_re = re.compile(r"""(%{0,2}
307 _help_end_re = re.compile(r"""(%{0,2}
308 [a-zA-Z_*][\w*]* # Variable name
308 [a-zA-Z_*][\w*]* # Variable name
309 (\.[a-zA-Z_*][\w*]*)* # .etc.etc
309 (\.[a-zA-Z_*][\w*]*)* # .etc.etc
310 )
310 )
311 (\?\??)$ # ? or ??
311 (\?\??)$ # ? or ??
312 """,
312 """,
313 re.VERBOSE)
313 re.VERBOSE)
314
314
315 class HelpEnd(TokenTransformBase):
315 class HelpEnd(TokenTransformBase):
316 # This needs to be higher priority (lower number) than EscapedCommand so
316 # This needs to be higher priority (lower number) than EscapedCommand so
317 # that inspecting magics (%foo?) works.
317 # that inspecting magics (%foo?) works.
318 priority = 5
318 priority = 5
319
319
320 def __init__(self, start, q_locn):
320 def __init__(self, start, q_locn):
321 super().__init__(start)
321 super().__init__(start)
322 self.q_line = q_locn[0] - 1 # Shift from 1-indexed to 0-indexed
322 self.q_line = q_locn[0] - 1 # Shift from 1-indexed to 0-indexed
323 self.q_col = q_locn[1]
323 self.q_col = q_locn[1]
324
324
325 @classmethod
325 @classmethod
326 def find(cls, tokens_by_line):
326 def find(cls, tokens_by_line):
327 for line in tokens_by_line:
327 for line in tokens_by_line:
328 # Last token is NEWLINE; look at last but one
328 # Last token is NEWLINE; look at last but one
329 if len(line) > 2 and line[-2].string == '?':
329 if len(line) > 2 and line[-2].string == '?':
330 # Find the first token that's not INDENT/DEDENT
330 # Find the first token that's not INDENT/DEDENT
331 ix = 0
331 ix = 0
332 while line[ix].type in {tokenize2.INDENT, tokenize2.DEDENT}:
332 while line[ix].type in {tokenize2.INDENT, tokenize2.DEDENT}:
333 ix += 1
333 ix += 1
334 return cls(line[ix].start, line[-2].start)
334 return cls(line[ix].start, line[-2].start)
335
335
336 def transform(self, lines):
336 def transform(self, lines):
337 piece = ''.join(lines[self.start_line:self.q_line+1])
337 piece = ''.join(lines[self.start_line:self.q_line+1])
338 indent, content = piece[:self.start_col], piece[self.start_col:]
338 indent, content = piece[:self.start_col], piece[self.start_col:]
339 lines_before = lines[:self.start_line]
339 lines_before = lines[:self.start_line]
340 lines_after = lines[self.q_line + 1:]
340 lines_after = lines[self.q_line + 1:]
341
341
342 m = _help_end_re.search(content)
342 m = _help_end_re.search(content)
343 assert m is not None, content
343 assert m is not None, content
344 target = m.group(1)
344 target = m.group(1)
345 esc = m.group(3)
345 esc = m.group(3)
346
346
347 # If we're mid-command, put it back on the next prompt for the user.
347 # If we're mid-command, put it back on the next prompt for the user.
348 next_input = None
348 next_input = None
349 if (not lines_before) and (not lines_after) \
349 if (not lines_before) and (not lines_after) \
350 and content.strip() != m.group(0):
350 and content.strip() != m.group(0):
351 next_input = content.rstrip('?\n')
351 next_input = content.rstrip('?\n')
352
352
353 call = _make_help_call(target, esc, next_input=next_input)
353 call = _make_help_call(target, esc, next_input=next_input)
354 new_line = indent + call + '\n'
354 new_line = indent + call + '\n'
355
355
356 return lines_before + [new_line] + lines_after
356 return lines_before + [new_line] + lines_after
357
357
358 def make_tokens_by_line(lines):
358 def make_tokens_by_line(lines):
359 tokens_by_line = [[]]
359 tokens_by_line = [[]]
360 for token in generate_tokens(iter(lines).__next__):
360 for token in generate_tokens(iter(lines).__next__):
361 tokens_by_line[-1].append(token)
361 tokens_by_line[-1].append(token)
362 if token.type == tokenize2.NEWLINE:
362 if token.type == tokenize2.NEWLINE:
363 tokens_by_line.append([])
363 tokens_by_line.append([])
364
364
365 return tokens_by_line
365 return tokens_by_line
366
366
367 def show_linewise_tokens(s: str):
367 def show_linewise_tokens(s: str):
368 """For investigation"""
368 """For investigation"""
369 if not s.endswith('\n'):
369 if not s.endswith('\n'):
370 s += '\n'
370 s += '\n'
371 lines = s.splitlines(keepends=True)
371 lines = s.splitlines(keepends=True)
372 for line in make_tokens_by_line(lines):
372 for line in make_tokens_by_line(lines):
373 print("Line -------")
373 print("Line -------")
374 for tokinfo in line:
374 for tokinfo in line:
375 print(" ", tokinfo)
375 print(" ", tokinfo)
376
376
377 class TransformerManager:
377 class TransformerManager:
378 def __init__(self):
378 def __init__(self):
379 self.cleanup_transforms = [
379 self.cleanup_transforms = [
380 leading_indent,
380 leading_indent,
381 classic_prompt,
381 classic_prompt,
382 ipython_prompt,
382 ipython_prompt,
383 ]
383 ]
384 self.line_transforms = [
384 self.line_transforms = [
385 cell_magic,
385 cell_magic,
386 ]
386 ]
387 self.token_transformers = [
387 self.token_transformers = [
388 MagicAssign,
388 MagicAssign,
389 SystemAssign,
389 SystemAssign,
390 EscapedCommand,
390 EscapedCommand,
391 HelpEnd,
391 HelpEnd,
392 ]
392 ]
393
393
394 def do_one_token_transform(self, lines):
394 def do_one_token_transform(self, lines):
395 """Find and run the transform earliest in the code.
395 """Find and run the transform earliest in the code.
396
396
397 Returns (changed, lines).
397 Returns (changed, lines).
398
398
399 This method is called repeatedly until changed is False, indicating
399 This method is called repeatedly until changed is False, indicating
400 that all available transformations are complete.
400 that all available transformations are complete.
401
401
402 The tokens following IPython special syntax might not be valid, so
402 The tokens following IPython special syntax might not be valid, so
403 the transformed code is retokenised every time to identify the next
403 the transformed code is retokenised every time to identify the next
404 piece of special syntax. Hopefully long code cells are mostly valid
404 piece of special syntax. Hopefully long code cells are mostly valid
405 Python, not using lots of IPython special syntax, so this shouldn't be
405 Python, not using lots of IPython special syntax, so this shouldn't be
406 a performance issue.
406 a performance issue.
407 """
407 """
408 tokens_by_line = make_tokens_by_line(lines)
408 tokens_by_line = make_tokens_by_line(lines)
409 candidates = []
409 candidates = []
410 for transformer_cls in self.token_transformers:
410 for transformer_cls in self.token_transformers:
411 transformer = transformer_cls.find(tokens_by_line)
411 transformer = transformer_cls.find(tokens_by_line)
412 if transformer:
412 if transformer:
413 candidates.append(transformer)
413 candidates.append(transformer)
414
414
415 if not candidates:
415 if not candidates:
416 # Nothing to transform
416 # Nothing to transform
417 return False, lines
417 return False, lines
418
418
419 transformer = min(candidates, key=TokenTransformBase.sortby)
419 transformer = min(candidates, key=TokenTransformBase.sortby)
420 return True, transformer.transform(lines)
420 return True, transformer.transform(lines)
421
421
422 def do_token_transforms(self, lines):
422 def do_token_transforms(self, lines):
423 while True:
423 while True:
424 changed, lines = self.do_one_token_transform(lines)
424 changed, lines = self.do_one_token_transform(lines)
425 if not changed:
425 if not changed:
426 return lines
426 return lines
427
427
428 def transform_cell(self, cell: str):
428 def transform_cell(self, cell: str):
429 if not cell.endswith('\n'):
429 if not cell.endswith('\n'):
430 cell += '\n' # Ensure every line has a newline
430 cell += '\n' # Ensure the cell has a trailing newline
431 lines = cell.splitlines(keepends=True)
431 lines = cell.splitlines(keepends=True)
432 for transform in self.cleanup_transforms + self.line_transforms:
432 for transform in self.cleanup_transforms + self.line_transforms:
433 #print(transform, lines)
433 #print(transform, lines)
434 lines = transform(lines)
434 lines = transform(lines)
435
435
436 lines = self.do_token_transforms(lines)
436 lines = self.do_token_transforms(lines)
437 return ''.join(lines)
437 return ''.join(lines)
438
438
439 def check_complete(self, cell: str):
439 def check_complete(self, cell: str):
440 """Return whether a block of code is ready to execute, or should be continued
440 """Return whether a block of code is ready to execute, or should be continued
441
441
442 Parameters
442 Parameters
443 ----------
443 ----------
444 source : string
444 source : string
445 Python input code, which can be multiline.
445 Python input code, which can be multiline.
446
446
447 Returns
447 Returns
448 -------
448 -------
449 status : str
449 status : str
450 One of 'complete', 'incomplete', or 'invalid' if source is not a
450 One of 'complete', 'incomplete', or 'invalid' if source is not a
451 prefix of valid code.
451 prefix of valid code.
452 indent_spaces : int or None
452 indent_spaces : int or None
453 The number of spaces by which to indent the next line of code. If
453 The number of spaces by which to indent the next line of code. If
454 status is not 'incomplete', this is None.
454 status is not 'incomplete', this is None.
455 """
455 """
456 if not cell.endswith('\n'):
456 if not cell.endswith('\n'):
457 cell += '\n' # Ensure every line has a newline
457 cell += '\n' # Ensure the cell has a trailing newline
458 lines = cell.splitlines(keepends=True)
458 lines = cell.splitlines(keepends=True)
459 if lines[-1][:-1].endswith('\\'):
459 if lines[-1][:-1].endswith('\\'):
460 # Explicit backslash continuation
460 # Explicit backslash continuation
461 return 'incomplete', find_last_indent(lines)
461 return 'incomplete', find_last_indent(lines)
462
462
463 try:
463 try:
464 for transform in self.cleanup_transforms:
464 for transform in self.cleanup_transforms:
465 lines = transform(lines)
465 lines = transform(lines)
466 except SyntaxError:
466 except SyntaxError:
467 return 'invalid', None
467 return 'invalid', None
468
468
469 if lines[0].startswith('%%'):
469 if lines[0].startswith('%%'):
470 # Special case for cell magics - completion marked by blank line
470 # Special case for cell magics - completion marked by blank line
471 if lines[-1].strip():
471 if lines[-1].strip():
472 return 'incomplete', find_last_indent(lines)
472 return 'incomplete', find_last_indent(lines)
473 else:
473 else:
474 return 'complete', None
474 return 'complete', None
475
475
476 try:
476 try:
477 for transform in self.line_transforms:
477 for transform in self.line_transforms:
478 lines = transform(lines)
478 lines = transform(lines)
479 lines = self.do_token_transforms(lines)
479 lines = self.do_token_transforms(lines)
480 except SyntaxError:
480 except SyntaxError:
481 return 'invalid', None
481 return 'invalid', None
482
482
483 tokens_by_line = make_tokens_by_line(lines)
483 tokens_by_line = make_tokens_by_line(lines)
484 if tokens_by_line[-1][-1].type != tokenize2.ENDMARKER:
484 if tokens_by_line[-1][-1].type != tokenize2.ENDMARKER:
485 # We're in a multiline string or expression
485 # We're in a multiline string or expression
486 return 'incomplete', find_last_indent(lines)
486 return 'incomplete', find_last_indent(lines)
487
487
488 # Find the last token on the previous line that's not NEWLINE or COMMENT
488 # Find the last token on the previous line that's not NEWLINE or COMMENT
489 toks_last_line = tokens_by_line[-2]
489 toks_last_line = tokens_by_line[-2]
490 ix = len(toks_last_line) - 1
490 ix = len(toks_last_line) - 1
491 while ix >= 0 and toks_last_line[ix].type in {tokenize2.NEWLINE,
491 while ix >= 0 and toks_last_line[ix].type in {tokenize2.NEWLINE,
492 tokenize2.COMMENT}:
492 tokenize2.COMMENT}:
493 ix -= 1
493 ix -= 1
494
494
495 if toks_last_line[ix].string == ':':
495 if toks_last_line[ix].string == ':':
496 # The last line starts a block (e.g. 'if foo:')
496 # The last line starts a block (e.g. 'if foo:')
497 ix = 0
497 ix = 0
498 while toks_last_line[ix].type in {tokenize2.INDENT, tokenize2.DEDENT}:
498 while toks_last_line[ix].type in {tokenize2.INDENT, tokenize2.DEDENT}:
499 ix += 1
499 ix += 1
500 indent = toks_last_line[ix].start[1]
500 indent = toks_last_line[ix].start[1]
501 return 'incomplete', indent + 4
501 return 'incomplete', indent + 4
502
502
503 # If there's a blank line at the end, assume we're ready to execute.
503 # If there's a blank line at the end, assume we're ready to execute.
504 if not lines[-1].strip():
504 if not lines[-1].strip():
505 return 'complete', None
505 return 'complete', None
506
506
507 # At this point, our checks think the code is complete (or invalid).
507 # At this point, our checks think the code is complete (or invalid).
508 # We'll use codeop.compile_command to check this with the real parser.
508 # We'll use codeop.compile_command to check this with the real parser.
509
509
510 try:
510 try:
511 res = compile_command(''.join(lines), symbol='exec')
511 res = compile_command(''.join(lines), symbol='exec')
512 except (SyntaxError, OverflowError, ValueError, TypeError,
512 except (SyntaxError, OverflowError, ValueError, TypeError,
513 MemoryError, SyntaxWarning):
513 MemoryError, SyntaxWarning):
514 return 'invalid', None
514 return 'invalid', None
515 else:
515 else:
516 if res is None:
516 if res is None:
517 return 'incomplete', find_last_indent(lines)
517 return 'incomplete', find_last_indent(lines)
518 return 'complete', None
518 return 'complete', None
519
519
520
520
521 def find_last_indent(lines):
521 def find_last_indent(lines):
522 m = _indent_re.match(lines[-1])
522 m = _indent_re.match(lines[-1])
523 if not m:
523 if not m:
524 return 0
524 return 0
525 return len(m.group(0).replace('\t', ' '*4))
525 return len(m.group(0).replace('\t', ' '*4))
@@ -1,1424 +1,1424 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Implementation of execution-related magic functions."""
2 """Implementation of execution-related magic functions."""
3
3
4 # Copyright (c) IPython Development Team.
4 # Copyright (c) IPython Development Team.
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6
6
7
7
8 import ast
8 import ast
9 import bdb
9 import bdb
10 import builtins as builtin_mod
10 import builtins as builtin_mod
11 import gc
11 import gc
12 import itertools
12 import itertools
13 import os
13 import os
14 import shlex
14 import shlex
15 import sys
15 import sys
16 import time
16 import time
17 import timeit
17 import timeit
18 import math
18 import math
19 from pdb import Restart
19 from pdb import Restart
20
20
21 # cProfile was added in Python2.5
21 # cProfile was added in Python2.5
22 try:
22 try:
23 import cProfile as profile
23 import cProfile as profile
24 import pstats
24 import pstats
25 except ImportError:
25 except ImportError:
26 # profile isn't bundled by default in Debian for license reasons
26 # profile isn't bundled by default in Debian for license reasons
27 try:
27 try:
28 import profile, pstats
28 import profile, pstats
29 except ImportError:
29 except ImportError:
30 profile = pstats = None
30 profile = pstats = None
31
31
32 from IPython.core import oinspect
32 from IPython.core import oinspect
33 from IPython.core import magic_arguments
33 from IPython.core import magic_arguments
34 from IPython.core import page
34 from IPython.core import page
35 from IPython.core.error import UsageError
35 from IPython.core.error import UsageError
36 from IPython.core.macro import Macro
36 from IPython.core.macro import Macro
37 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
37 from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic,
38 line_cell_magic, on_off, needs_local_scope)
38 line_cell_magic, on_off, needs_local_scope)
39 from IPython.testing.skipdoctest import skip_doctest
39 from IPython.testing.skipdoctest import skip_doctest
40 from IPython.utils.contexts import preserve_keys
40 from IPython.utils.contexts import preserve_keys
41 from IPython.utils.capture import capture_output
41 from IPython.utils.capture import capture_output
42 from IPython.utils.ipstruct import Struct
42 from IPython.utils.ipstruct import Struct
43 from IPython.utils.module_paths import find_mod
43 from IPython.utils.module_paths import find_mod
44 from IPython.utils.path import get_py_filename, shellglob
44 from IPython.utils.path import get_py_filename, shellglob
45 from IPython.utils.timing import clock, clock2
45 from IPython.utils.timing import clock, clock2
46 from warnings import warn
46 from warnings import warn
47 from logging import error
47 from logging import error
48 from io import StringIO
48 from io import StringIO
49
49
50
50
51 #-----------------------------------------------------------------------------
51 #-----------------------------------------------------------------------------
52 # Magic implementation classes
52 # Magic implementation classes
53 #-----------------------------------------------------------------------------
53 #-----------------------------------------------------------------------------
54
54
55
55
56 class TimeitResult(object):
56 class TimeitResult(object):
57 """
57 """
58 Object returned by the timeit magic with info about the run.
58 Object returned by the timeit magic with info about the run.
59
59
60 Contains the following attributes :
60 Contains the following attributes :
61
61
62 loops: (int) number of loops done per measurement
62 loops: (int) number of loops done per measurement
63 repeat: (int) number of times the measurement has been repeated
63 repeat: (int) number of times the measurement has been repeated
64 best: (float) best execution time / number
64 best: (float) best execution time / number
65 all_runs: (list of float) execution time of each run (in s)
65 all_runs: (list of float) execution time of each run (in s)
66 compile_time: (float) time of statement compilation (s)
66 compile_time: (float) time of statement compilation (s)
67
67
68 """
68 """
69 def __init__(self, loops, repeat, best, worst, all_runs, compile_time, precision):
69 def __init__(self, loops, repeat, best, worst, all_runs, compile_time, precision):
70 self.loops = loops
70 self.loops = loops
71 self.repeat = repeat
71 self.repeat = repeat
72 self.best = best
72 self.best = best
73 self.worst = worst
73 self.worst = worst
74 self.all_runs = all_runs
74 self.all_runs = all_runs
75 self.compile_time = compile_time
75 self.compile_time = compile_time
76 self._precision = precision
76 self._precision = precision
77 self.timings = [ dt / self.loops for dt in all_runs]
77 self.timings = [ dt / self.loops for dt in all_runs]
78
78
79 @property
79 @property
80 def average(self):
80 def average(self):
81 return math.fsum(self.timings) / len(self.timings)
81 return math.fsum(self.timings) / len(self.timings)
82
82
83 @property
83 @property
84 def stdev(self):
84 def stdev(self):
85 mean = self.average
85 mean = self.average
86 return (math.fsum([(x - mean) ** 2 for x in self.timings]) / len(self.timings)) ** 0.5
86 return (math.fsum([(x - mean) ** 2 for x in self.timings]) / len(self.timings)) ** 0.5
87
87
88 def __str__(self):
88 def __str__(self):
89 pm = '+-'
89 pm = '+-'
90 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
90 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
91 try:
91 try:
92 u'\xb1'.encode(sys.stdout.encoding)
92 u'\xb1'.encode(sys.stdout.encoding)
93 pm = u'\xb1'
93 pm = u'\xb1'
94 except:
94 except:
95 pass
95 pass
96 return (
96 return (
97 u"{mean} {pm} {std} per loop (mean {pm} std. dev. of {runs} run{run_plural}, {loops} loop{loop_plural} each)"
97 u"{mean} {pm} {std} per loop (mean {pm} std. dev. of {runs} run{run_plural}, {loops} loop{loop_plural} each)"
98 .format(
98 .format(
99 pm = pm,
99 pm = pm,
100 runs = self.repeat,
100 runs = self.repeat,
101 loops = self.loops,
101 loops = self.loops,
102 loop_plural = "" if self.loops == 1 else "s",
102 loop_plural = "" if self.loops == 1 else "s",
103 run_plural = "" if self.repeat == 1 else "s",
103 run_plural = "" if self.repeat == 1 else "s",
104 mean = _format_time(self.average, self._precision),
104 mean = _format_time(self.average, self._precision),
105 std = _format_time(self.stdev, self._precision))
105 std = _format_time(self.stdev, self._precision))
106 )
106 )
107
107
108 def _repr_pretty_(self, p , cycle):
108 def _repr_pretty_(self, p , cycle):
109 unic = self.__str__()
109 unic = self.__str__()
110 p.text(u'<TimeitResult : '+unic+u'>')
110 p.text(u'<TimeitResult : '+unic+u'>')
111
111
112
112
113
113
114 class TimeitTemplateFiller(ast.NodeTransformer):
114 class TimeitTemplateFiller(ast.NodeTransformer):
115 """Fill in the AST template for timing execution.
115 """Fill in the AST template for timing execution.
116
116
117 This is quite closely tied to the template definition, which is in
117 This is quite closely tied to the template definition, which is in
118 :meth:`ExecutionMagics.timeit`.
118 :meth:`ExecutionMagics.timeit`.
119 """
119 """
120 def __init__(self, ast_setup, ast_stmt):
120 def __init__(self, ast_setup, ast_stmt):
121 self.ast_setup = ast_setup
121 self.ast_setup = ast_setup
122 self.ast_stmt = ast_stmt
122 self.ast_stmt = ast_stmt
123
123
124 def visit_FunctionDef(self, node):
124 def visit_FunctionDef(self, node):
125 "Fill in the setup statement"
125 "Fill in the setup statement"
126 self.generic_visit(node)
126 self.generic_visit(node)
127 if node.name == "inner":
127 if node.name == "inner":
128 node.body[:1] = self.ast_setup.body
128 node.body[:1] = self.ast_setup.body
129
129
130 return node
130 return node
131
131
132 def visit_For(self, node):
132 def visit_For(self, node):
133 "Fill in the statement to be timed"
133 "Fill in the statement to be timed"
134 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
134 if getattr(getattr(node.body[0], 'value', None), 'id', None) == 'stmt':
135 node.body = self.ast_stmt.body
135 node.body = self.ast_stmt.body
136 return node
136 return node
137
137
138
138
139 class Timer(timeit.Timer):
139 class Timer(timeit.Timer):
140 """Timer class that explicitly uses self.inner
140 """Timer class that explicitly uses self.inner
141
141
142 which is an undocumented implementation detail of CPython,
142 which is an undocumented implementation detail of CPython,
143 not shared by PyPy.
143 not shared by PyPy.
144 """
144 """
145 # Timer.timeit copied from CPython 3.4.2
145 # Timer.timeit copied from CPython 3.4.2
146 def timeit(self, number=timeit.default_number):
146 def timeit(self, number=timeit.default_number):
147 """Time 'number' executions of the main statement.
147 """Time 'number' executions of the main statement.
148
148
149 To be precise, this executes the setup statement once, and
149 To be precise, this executes the setup statement once, and
150 then returns the time it takes to execute the main statement
150 then returns the time it takes to execute the main statement
151 a number of times, as a float measured in seconds. The
151 a number of times, as a float measured in seconds. The
152 argument is the number of times through the loop, defaulting
152 argument is the number of times through the loop, defaulting
153 to one million. The main statement, the setup statement and
153 to one million. The main statement, the setup statement and
154 the timer function to be used are passed to the constructor.
154 the timer function to be used are passed to the constructor.
155 """
155 """
156 it = itertools.repeat(None, number)
156 it = itertools.repeat(None, number)
157 gcold = gc.isenabled()
157 gcold = gc.isenabled()
158 gc.disable()
158 gc.disable()
159 try:
159 try:
160 timing = self.inner(it, self.timer)
160 timing = self.inner(it, self.timer)
161 finally:
161 finally:
162 if gcold:
162 if gcold:
163 gc.enable()
163 gc.enable()
164 return timing
164 return timing
165
165
166
166
167 @magics_class
167 @magics_class
168 class ExecutionMagics(Magics):
168 class ExecutionMagics(Magics):
169 """Magics related to code execution, debugging, profiling, etc.
169 """Magics related to code execution, debugging, profiling, etc.
170
170
171 """
171 """
172
172
173 def __init__(self, shell):
173 def __init__(self, shell):
174 super(ExecutionMagics, self).__init__(shell)
174 super(ExecutionMagics, self).__init__(shell)
175 if profile is None:
175 if profile is None:
176 self.prun = self.profile_missing_notice
176 self.prun = self.profile_missing_notice
177 # Default execution function used to actually run user code.
177 # Default execution function used to actually run user code.
178 self.default_runner = None
178 self.default_runner = None
179
179
180 def profile_missing_notice(self, *args, **kwargs):
180 def profile_missing_notice(self, *args, **kwargs):
181 error("""\
181 error("""\
182 The profile module could not be found. It has been removed from the standard
182 The profile module could not be found. It has been removed from the standard
183 python packages because of its non-free license. To use profiling, install the
183 python packages because of its non-free license. To use profiling, install the
184 python-profiler package from non-free.""")
184 python-profiler package from non-free.""")
185
185
186 @skip_doctest
186 @skip_doctest
187 @line_cell_magic
187 @line_cell_magic
188 def prun(self, parameter_s='', cell=None):
188 def prun(self, parameter_s='', cell=None):
189
189
190 """Run a statement through the python code profiler.
190 """Run a statement through the python code profiler.
191
191
192 Usage, in line mode:
192 Usage, in line mode:
193 %prun [options] statement
193 %prun [options] statement
194
194
195 Usage, in cell mode:
195 Usage, in cell mode:
196 %%prun [options] [statement]
196 %%prun [options] [statement]
197 code...
197 code...
198 code...
198 code...
199
199
200 In cell mode, the additional code lines are appended to the (possibly
200 In cell mode, the additional code lines are appended to the (possibly
201 empty) statement in the first line. Cell mode allows you to easily
201 empty) statement in the first line. Cell mode allows you to easily
202 profile multiline blocks without having to put them in a separate
202 profile multiline blocks without having to put them in a separate
203 function.
203 function.
204
204
205 The given statement (which doesn't require quote marks) is run via the
205 The given statement (which doesn't require quote marks) is run via the
206 python profiler in a manner similar to the profile.run() function.
206 python profiler in a manner similar to the profile.run() function.
207 Namespaces are internally managed to work correctly; profile.run
207 Namespaces are internally managed to work correctly; profile.run
208 cannot be used in IPython because it makes certain assumptions about
208 cannot be used in IPython because it makes certain assumptions about
209 namespaces which do not hold under IPython.
209 namespaces which do not hold under IPython.
210
210
211 Options:
211 Options:
212
212
213 -l <limit>
213 -l <limit>
214 you can place restrictions on what or how much of the
214 you can place restrictions on what or how much of the
215 profile gets printed. The limit value can be:
215 profile gets printed. The limit value can be:
216
216
217 * A string: only information for function names containing this string
217 * A string: only information for function names containing this string
218 is printed.
218 is printed.
219
219
220 * An integer: only these many lines are printed.
220 * An integer: only these many lines are printed.
221
221
222 * A float (between 0 and 1): this fraction of the report is printed
222 * A float (between 0 and 1): this fraction of the report is printed
223 (for example, use a limit of 0.4 to see the topmost 40% only).
223 (for example, use a limit of 0.4 to see the topmost 40% only).
224
224
225 You can combine several limits with repeated use of the option. For
225 You can combine several limits with repeated use of the option. For
226 example, ``-l __init__ -l 5`` will print only the topmost 5 lines of
226 example, ``-l __init__ -l 5`` will print only the topmost 5 lines of
227 information about class constructors.
227 information about class constructors.
228
228
229 -r
229 -r
230 return the pstats.Stats object generated by the profiling. This
230 return the pstats.Stats object generated by the profiling. This
231 object has all the information about the profile in it, and you can
231 object has all the information about the profile in it, and you can
232 later use it for further analysis or in other functions.
232 later use it for further analysis or in other functions.
233
233
234 -s <key>
234 -s <key>
235 sort profile by given key. You can provide more than one key
235 sort profile by given key. You can provide more than one key
236 by using the option several times: '-s key1 -s key2 -s key3...'. The
236 by using the option several times: '-s key1 -s key2 -s key3...'. The
237 default sorting key is 'time'.
237 default sorting key is 'time'.
238
238
239 The following is copied verbatim from the profile documentation
239 The following is copied verbatim from the profile documentation
240 referenced below:
240 referenced below:
241
241
242 When more than one key is provided, additional keys are used as
242 When more than one key is provided, additional keys are used as
243 secondary criteria when the there is equality in all keys selected
243 secondary criteria when the there is equality in all keys selected
244 before them.
244 before them.
245
245
246 Abbreviations can be used for any key names, as long as the
246 Abbreviations can be used for any key names, as long as the
247 abbreviation is unambiguous. The following are the keys currently
247 abbreviation is unambiguous. The following are the keys currently
248 defined:
248 defined:
249
249
250 ============ =====================
250 ============ =====================
251 Valid Arg Meaning
251 Valid Arg Meaning
252 ============ =====================
252 ============ =====================
253 "calls" call count
253 "calls" call count
254 "cumulative" cumulative time
254 "cumulative" cumulative time
255 "file" file name
255 "file" file name
256 "module" file name
256 "module" file name
257 "pcalls" primitive call count
257 "pcalls" primitive call count
258 "line" line number
258 "line" line number
259 "name" function name
259 "name" function name
260 "nfl" name/file/line
260 "nfl" name/file/line
261 "stdname" standard name
261 "stdname" standard name
262 "time" internal time
262 "time" internal time
263 ============ =====================
263 ============ =====================
264
264
265 Note that all sorts on statistics are in descending order (placing
265 Note that all sorts on statistics are in descending order (placing
266 most time consuming items first), where as name, file, and line number
266 most time consuming items first), where as name, file, and line number
267 searches are in ascending order (i.e., alphabetical). The subtle
267 searches are in ascending order (i.e., alphabetical). The subtle
268 distinction between "nfl" and "stdname" is that the standard name is a
268 distinction between "nfl" and "stdname" is that the standard name is a
269 sort of the name as printed, which means that the embedded line
269 sort of the name as printed, which means that the embedded line
270 numbers get compared in an odd way. For example, lines 3, 20, and 40
270 numbers get compared in an odd way. For example, lines 3, 20, and 40
271 would (if the file names were the same) appear in the string order
271 would (if the file names were the same) appear in the string order
272 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
272 "20" "3" and "40". In contrast, "nfl" does a numeric compare of the
273 line numbers. In fact, sort_stats("nfl") is the same as
273 line numbers. In fact, sort_stats("nfl") is the same as
274 sort_stats("name", "file", "line").
274 sort_stats("name", "file", "line").
275
275
276 -T <filename>
276 -T <filename>
277 save profile results as shown on screen to a text
277 save profile results as shown on screen to a text
278 file. The profile is still shown on screen.
278 file. The profile is still shown on screen.
279
279
280 -D <filename>
280 -D <filename>
281 save (via dump_stats) profile statistics to given
281 save (via dump_stats) profile statistics to given
282 filename. This data is in a format understood by the pstats module, and
282 filename. This data is in a format understood by the pstats module, and
283 is generated by a call to the dump_stats() method of profile
283 is generated by a call to the dump_stats() method of profile
284 objects. The profile is still shown on screen.
284 objects. The profile is still shown on screen.
285
285
286 -q
286 -q
287 suppress output to the pager. Best used with -T and/or -D above.
287 suppress output to the pager. Best used with -T and/or -D above.
288
288
289 If you want to run complete programs under the profiler's control, use
289 If you want to run complete programs under the profiler's control, use
290 ``%run -p [prof_opts] filename.py [args to program]`` where prof_opts
290 ``%run -p [prof_opts] filename.py [args to program]`` where prof_opts
291 contains profiler specific options as described here.
291 contains profiler specific options as described here.
292
292
293 You can read the complete documentation for the profile module with::
293 You can read the complete documentation for the profile module with::
294
294
295 In [1]: import profile; profile.help()
295 In [1]: import profile; profile.help()
296 """
296 """
297 opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q',
297 opts, arg_str = self.parse_options(parameter_s, 'D:l:rs:T:q',
298 list_all=True, posix=False)
298 list_all=True, posix=False)
299 if cell is not None:
299 if cell is not None:
300 arg_str += '\n' + cell
300 arg_str += '\n' + cell
301 arg_str = self.shell.input_splitter.transform_cell(arg_str)
301 arg_str = self.shell.input_transformer_manager.transform_cell(arg_str)
302 return self._run_with_profiler(arg_str, opts, self.shell.user_ns)
302 return self._run_with_profiler(arg_str, opts, self.shell.user_ns)
303
303
304 def _run_with_profiler(self, code, opts, namespace):
304 def _run_with_profiler(self, code, opts, namespace):
305 """
305 """
306 Run `code` with profiler. Used by ``%prun`` and ``%run -p``.
306 Run `code` with profiler. Used by ``%prun`` and ``%run -p``.
307
307
308 Parameters
308 Parameters
309 ----------
309 ----------
310 code : str
310 code : str
311 Code to be executed.
311 Code to be executed.
312 opts : Struct
312 opts : Struct
313 Options parsed by `self.parse_options`.
313 Options parsed by `self.parse_options`.
314 namespace : dict
314 namespace : dict
315 A dictionary for Python namespace (e.g., `self.shell.user_ns`).
315 A dictionary for Python namespace (e.g., `self.shell.user_ns`).
316
316
317 """
317 """
318
318
319 # Fill default values for unspecified options:
319 # Fill default values for unspecified options:
320 opts.merge(Struct(D=[''], l=[], s=['time'], T=['']))
320 opts.merge(Struct(D=[''], l=[], s=['time'], T=['']))
321
321
322 prof = profile.Profile()
322 prof = profile.Profile()
323 try:
323 try:
324 prof = prof.runctx(code, namespace, namespace)
324 prof = prof.runctx(code, namespace, namespace)
325 sys_exit = ''
325 sys_exit = ''
326 except SystemExit:
326 except SystemExit:
327 sys_exit = """*** SystemExit exception caught in code being profiled."""
327 sys_exit = """*** SystemExit exception caught in code being profiled."""
328
328
329 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
329 stats = pstats.Stats(prof).strip_dirs().sort_stats(*opts.s)
330
330
331 lims = opts.l
331 lims = opts.l
332 if lims:
332 if lims:
333 lims = [] # rebuild lims with ints/floats/strings
333 lims = [] # rebuild lims with ints/floats/strings
334 for lim in opts.l:
334 for lim in opts.l:
335 try:
335 try:
336 lims.append(int(lim))
336 lims.append(int(lim))
337 except ValueError:
337 except ValueError:
338 try:
338 try:
339 lims.append(float(lim))
339 lims.append(float(lim))
340 except ValueError:
340 except ValueError:
341 lims.append(lim)
341 lims.append(lim)
342
342
343 # Trap output.
343 # Trap output.
344 stdout_trap = StringIO()
344 stdout_trap = StringIO()
345 stats_stream = stats.stream
345 stats_stream = stats.stream
346 try:
346 try:
347 stats.stream = stdout_trap
347 stats.stream = stdout_trap
348 stats.print_stats(*lims)
348 stats.print_stats(*lims)
349 finally:
349 finally:
350 stats.stream = stats_stream
350 stats.stream = stats_stream
351
351
352 output = stdout_trap.getvalue()
352 output = stdout_trap.getvalue()
353 output = output.rstrip()
353 output = output.rstrip()
354
354
355 if 'q' not in opts:
355 if 'q' not in opts:
356 page.page(output)
356 page.page(output)
357 print(sys_exit, end=' ')
357 print(sys_exit, end=' ')
358
358
359 dump_file = opts.D[0]
359 dump_file = opts.D[0]
360 text_file = opts.T[0]
360 text_file = opts.T[0]
361 if dump_file:
361 if dump_file:
362 prof.dump_stats(dump_file)
362 prof.dump_stats(dump_file)
363 print('\n*** Profile stats marshalled to file',\
363 print('\n*** Profile stats marshalled to file',\
364 repr(dump_file)+'.',sys_exit)
364 repr(dump_file)+'.',sys_exit)
365 if text_file:
365 if text_file:
366 pfile = open(text_file,'w')
366 pfile = open(text_file,'w')
367 pfile.write(output)
367 pfile.write(output)
368 pfile.close()
368 pfile.close()
369 print('\n*** Profile printout saved to text file',\
369 print('\n*** Profile printout saved to text file',\
370 repr(text_file)+'.',sys_exit)
370 repr(text_file)+'.',sys_exit)
371
371
372 if 'r' in opts:
372 if 'r' in opts:
373 return stats
373 return stats
374 else:
374 else:
375 return None
375 return None
376
376
377 @line_magic
377 @line_magic
378 def pdb(self, parameter_s=''):
378 def pdb(self, parameter_s=''):
379 """Control the automatic calling of the pdb interactive debugger.
379 """Control the automatic calling of the pdb interactive debugger.
380
380
381 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
381 Call as '%pdb on', '%pdb 1', '%pdb off' or '%pdb 0'. If called without
382 argument it works as a toggle.
382 argument it works as a toggle.
383
383
384 When an exception is triggered, IPython can optionally call the
384 When an exception is triggered, IPython can optionally call the
385 interactive pdb debugger after the traceback printout. %pdb toggles
385 interactive pdb debugger after the traceback printout. %pdb toggles
386 this feature on and off.
386 this feature on and off.
387
387
388 The initial state of this feature is set in your configuration
388 The initial state of this feature is set in your configuration
389 file (the option is ``InteractiveShell.pdb``).
389 file (the option is ``InteractiveShell.pdb``).
390
390
391 If you want to just activate the debugger AFTER an exception has fired,
391 If you want to just activate the debugger AFTER an exception has fired,
392 without having to type '%pdb on' and rerunning your code, you can use
392 without having to type '%pdb on' and rerunning your code, you can use
393 the %debug magic."""
393 the %debug magic."""
394
394
395 par = parameter_s.strip().lower()
395 par = parameter_s.strip().lower()
396
396
397 if par:
397 if par:
398 try:
398 try:
399 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
399 new_pdb = {'off':0,'0':0,'on':1,'1':1}[par]
400 except KeyError:
400 except KeyError:
401 print ('Incorrect argument. Use on/1, off/0, '
401 print ('Incorrect argument. Use on/1, off/0, '
402 'or nothing for a toggle.')
402 'or nothing for a toggle.')
403 return
403 return
404 else:
404 else:
405 # toggle
405 # toggle
406 new_pdb = not self.shell.call_pdb
406 new_pdb = not self.shell.call_pdb
407
407
408 # set on the shell
408 # set on the shell
409 self.shell.call_pdb = new_pdb
409 self.shell.call_pdb = new_pdb
410 print('Automatic pdb calling has been turned',on_off(new_pdb))
410 print('Automatic pdb calling has been turned',on_off(new_pdb))
411
411
412 @skip_doctest
412 @skip_doctest
413 @magic_arguments.magic_arguments()
413 @magic_arguments.magic_arguments()
414 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
414 @magic_arguments.argument('--breakpoint', '-b', metavar='FILE:LINE',
415 help="""
415 help="""
416 Set break point at LINE in FILE.
416 Set break point at LINE in FILE.
417 """
417 """
418 )
418 )
419 @magic_arguments.argument('statement', nargs='*',
419 @magic_arguments.argument('statement', nargs='*',
420 help="""
420 help="""
421 Code to run in debugger.
421 Code to run in debugger.
422 You can omit this in cell magic mode.
422 You can omit this in cell magic mode.
423 """
423 """
424 )
424 )
425 @line_cell_magic
425 @line_cell_magic
426 def debug(self, line='', cell=None):
426 def debug(self, line='', cell=None):
427 """Activate the interactive debugger.
427 """Activate the interactive debugger.
428
428
429 This magic command support two ways of activating debugger.
429 This magic command support two ways of activating debugger.
430 One is to activate debugger before executing code. This way, you
430 One is to activate debugger before executing code. This way, you
431 can set a break point, to step through the code from the point.
431 can set a break point, to step through the code from the point.
432 You can use this mode by giving statements to execute and optionally
432 You can use this mode by giving statements to execute and optionally
433 a breakpoint.
433 a breakpoint.
434
434
435 The other one is to activate debugger in post-mortem mode. You can
435 The other one is to activate debugger in post-mortem mode. You can
436 activate this mode simply running %debug without any argument.
436 activate this mode simply running %debug without any argument.
437 If an exception has just occurred, this lets you inspect its stack
437 If an exception has just occurred, this lets you inspect its stack
438 frames interactively. Note that this will always work only on the last
438 frames interactively. Note that this will always work only on the last
439 traceback that occurred, so you must call this quickly after an
439 traceback that occurred, so you must call this quickly after an
440 exception that you wish to inspect has fired, because if another one
440 exception that you wish to inspect has fired, because if another one
441 occurs, it clobbers the previous one.
441 occurs, it clobbers the previous one.
442
442
443 If you want IPython to automatically do this on every exception, see
443 If you want IPython to automatically do this on every exception, see
444 the %pdb magic for more details.
444 the %pdb magic for more details.
445 """
445 """
446 args = magic_arguments.parse_argstring(self.debug, line)
446 args = magic_arguments.parse_argstring(self.debug, line)
447
447
448 if not (args.breakpoint or args.statement or cell):
448 if not (args.breakpoint or args.statement or cell):
449 self._debug_post_mortem()
449 self._debug_post_mortem()
450 else:
450 else:
451 code = "\n".join(args.statement)
451 code = "\n".join(args.statement)
452 if cell:
452 if cell:
453 code += "\n" + cell
453 code += "\n" + cell
454 self._debug_exec(code, args.breakpoint)
454 self._debug_exec(code, args.breakpoint)
455
455
456 def _debug_post_mortem(self):
456 def _debug_post_mortem(self):
457 self.shell.debugger(force=True)
457 self.shell.debugger(force=True)
458
458
459 def _debug_exec(self, code, breakpoint):
459 def _debug_exec(self, code, breakpoint):
460 if breakpoint:
460 if breakpoint:
461 (filename, bp_line) = breakpoint.rsplit(':', 1)
461 (filename, bp_line) = breakpoint.rsplit(':', 1)
462 bp_line = int(bp_line)
462 bp_line = int(bp_line)
463 else:
463 else:
464 (filename, bp_line) = (None, None)
464 (filename, bp_line) = (None, None)
465 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
465 self._run_with_debugger(code, self.shell.user_ns, filename, bp_line)
466
466
467 @line_magic
467 @line_magic
468 def tb(self, s):
468 def tb(self, s):
469 """Print the last traceback with the currently active exception mode.
469 """Print the last traceback with the currently active exception mode.
470
470
471 See %xmode for changing exception reporting modes."""
471 See %xmode for changing exception reporting modes."""
472 self.shell.showtraceback()
472 self.shell.showtraceback()
473
473
474 @skip_doctest
474 @skip_doctest
475 @line_magic
475 @line_magic
476 def run(self, parameter_s='', runner=None,
476 def run(self, parameter_s='', runner=None,
477 file_finder=get_py_filename):
477 file_finder=get_py_filename):
478 """Run the named file inside IPython as a program.
478 """Run the named file inside IPython as a program.
479
479
480 Usage::
480 Usage::
481
481
482 %run [-n -i -e -G]
482 %run [-n -i -e -G]
483 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
483 [( -t [-N<N>] | -d [-b<N>] | -p [profile options] )]
484 ( -m mod | file ) [args]
484 ( -m mod | file ) [args]
485
485
486 Parameters after the filename are passed as command-line arguments to
486 Parameters after the filename are passed as command-line arguments to
487 the program (put in sys.argv). Then, control returns to IPython's
487 the program (put in sys.argv). Then, control returns to IPython's
488 prompt.
488 prompt.
489
489
490 This is similar to running at a system prompt ``python file args``,
490 This is similar to running at a system prompt ``python file args``,
491 but with the advantage of giving you IPython's tracebacks, and of
491 but with the advantage of giving you IPython's tracebacks, and of
492 loading all variables into your interactive namespace for further use
492 loading all variables into your interactive namespace for further use
493 (unless -p is used, see below).
493 (unless -p is used, see below).
494
494
495 The file is executed in a namespace initially consisting only of
495 The file is executed in a namespace initially consisting only of
496 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
496 ``__name__=='__main__'`` and sys.argv constructed as indicated. It thus
497 sees its environment as if it were being run as a stand-alone program
497 sees its environment as if it were being run as a stand-alone program
498 (except for sharing global objects such as previously imported
498 (except for sharing global objects such as previously imported
499 modules). But after execution, the IPython interactive namespace gets
499 modules). But after execution, the IPython interactive namespace gets
500 updated with all variables defined in the program (except for __name__
500 updated with all variables defined in the program (except for __name__
501 and sys.argv). This allows for very convenient loading of code for
501 and sys.argv). This allows for very convenient loading of code for
502 interactive work, while giving each program a 'clean sheet' to run in.
502 interactive work, while giving each program a 'clean sheet' to run in.
503
503
504 Arguments are expanded using shell-like glob match. Patterns
504 Arguments are expanded using shell-like glob match. Patterns
505 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
505 '*', '?', '[seq]' and '[!seq]' can be used. Additionally,
506 tilde '~' will be expanded into user's home directory. Unlike
506 tilde '~' will be expanded into user's home directory. Unlike
507 real shells, quotation does not suppress expansions. Use
507 real shells, quotation does not suppress expansions. Use
508 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
508 *two* back slashes (e.g. ``\\\\*``) to suppress expansions.
509 To completely disable these expansions, you can use -G flag.
509 To completely disable these expansions, you can use -G flag.
510
510
511 Options:
511 Options:
512
512
513 -n
513 -n
514 __name__ is NOT set to '__main__', but to the running file's name
514 __name__ is NOT set to '__main__', but to the running file's name
515 without extension (as python does under import). This allows running
515 without extension (as python does under import). This allows running
516 scripts and reloading the definitions in them without calling code
516 scripts and reloading the definitions in them without calling code
517 protected by an ``if __name__ == "__main__"`` clause.
517 protected by an ``if __name__ == "__main__"`` clause.
518
518
519 -i
519 -i
520 run the file in IPython's namespace instead of an empty one. This
520 run the file in IPython's namespace instead of an empty one. This
521 is useful if you are experimenting with code written in a text editor
521 is useful if you are experimenting with code written in a text editor
522 which depends on variables defined interactively.
522 which depends on variables defined interactively.
523
523
524 -e
524 -e
525 ignore sys.exit() calls or SystemExit exceptions in the script
525 ignore sys.exit() calls or SystemExit exceptions in the script
526 being run. This is particularly useful if IPython is being used to
526 being run. This is particularly useful if IPython is being used to
527 run unittests, which always exit with a sys.exit() call. In such
527 run unittests, which always exit with a sys.exit() call. In such
528 cases you are interested in the output of the test results, not in
528 cases you are interested in the output of the test results, not in
529 seeing a traceback of the unittest module.
529 seeing a traceback of the unittest module.
530
530
531 -t
531 -t
532 print timing information at the end of the run. IPython will give
532 print timing information at the end of the run. IPython will give
533 you an estimated CPU time consumption for your script, which under
533 you an estimated CPU time consumption for your script, which under
534 Unix uses the resource module to avoid the wraparound problems of
534 Unix uses the resource module to avoid the wraparound problems of
535 time.clock(). Under Unix, an estimate of time spent on system tasks
535 time.clock(). Under Unix, an estimate of time spent on system tasks
536 is also given (for Windows platforms this is reported as 0.0).
536 is also given (for Windows platforms this is reported as 0.0).
537
537
538 If -t is given, an additional ``-N<N>`` option can be given, where <N>
538 If -t is given, an additional ``-N<N>`` option can be given, where <N>
539 must be an integer indicating how many times you want the script to
539 must be an integer indicating how many times you want the script to
540 run. The final timing report will include total and per run results.
540 run. The final timing report will include total and per run results.
541
541
542 For example (testing the script uniq_stable.py)::
542 For example (testing the script uniq_stable.py)::
543
543
544 In [1]: run -t uniq_stable
544 In [1]: run -t uniq_stable
545
545
546 IPython CPU timings (estimated):
546 IPython CPU timings (estimated):
547 User : 0.19597 s.
547 User : 0.19597 s.
548 System: 0.0 s.
548 System: 0.0 s.
549
549
550 In [2]: run -t -N5 uniq_stable
550 In [2]: run -t -N5 uniq_stable
551
551
552 IPython CPU timings (estimated):
552 IPython CPU timings (estimated):
553 Total runs performed: 5
553 Total runs performed: 5
554 Times : Total Per run
554 Times : Total Per run
555 User : 0.910862 s, 0.1821724 s.
555 User : 0.910862 s, 0.1821724 s.
556 System: 0.0 s, 0.0 s.
556 System: 0.0 s, 0.0 s.
557
557
558 -d
558 -d
559 run your program under the control of pdb, the Python debugger.
559 run your program under the control of pdb, the Python debugger.
560 This allows you to execute your program step by step, watch variables,
560 This allows you to execute your program step by step, watch variables,
561 etc. Internally, what IPython does is similar to calling::
561 etc. Internally, what IPython does is similar to calling::
562
562
563 pdb.run('execfile("YOURFILENAME")')
563 pdb.run('execfile("YOURFILENAME")')
564
564
565 with a breakpoint set on line 1 of your file. You can change the line
565 with a breakpoint set on line 1 of your file. You can change the line
566 number for this automatic breakpoint to be <N> by using the -bN option
566 number for this automatic breakpoint to be <N> by using the -bN option
567 (where N must be an integer). For example::
567 (where N must be an integer). For example::
568
568
569 %run -d -b40 myscript
569 %run -d -b40 myscript
570
570
571 will set the first breakpoint at line 40 in myscript.py. Note that
571 will set the first breakpoint at line 40 in myscript.py. Note that
572 the first breakpoint must be set on a line which actually does
572 the first breakpoint must be set on a line which actually does
573 something (not a comment or docstring) for it to stop execution.
573 something (not a comment or docstring) for it to stop execution.
574
574
575 Or you can specify a breakpoint in a different file::
575 Or you can specify a breakpoint in a different file::
576
576
577 %run -d -b myotherfile.py:20 myscript
577 %run -d -b myotherfile.py:20 myscript
578
578
579 When the pdb debugger starts, you will see a (Pdb) prompt. You must
579 When the pdb debugger starts, you will see a (Pdb) prompt. You must
580 first enter 'c' (without quotes) to start execution up to the first
580 first enter 'c' (without quotes) to start execution up to the first
581 breakpoint.
581 breakpoint.
582
582
583 Entering 'help' gives information about the use of the debugger. You
583 Entering 'help' gives information about the use of the debugger. You
584 can easily see pdb's full documentation with "import pdb;pdb.help()"
584 can easily see pdb's full documentation with "import pdb;pdb.help()"
585 at a prompt.
585 at a prompt.
586
586
587 -p
587 -p
588 run program under the control of the Python profiler module (which
588 run program under the control of the Python profiler module (which
589 prints a detailed report of execution times, function calls, etc).
589 prints a detailed report of execution times, function calls, etc).
590
590
591 You can pass other options after -p which affect the behavior of the
591 You can pass other options after -p which affect the behavior of the
592 profiler itself. See the docs for %prun for details.
592 profiler itself. See the docs for %prun for details.
593
593
594 In this mode, the program's variables do NOT propagate back to the
594 In this mode, the program's variables do NOT propagate back to the
595 IPython interactive namespace (because they remain in the namespace
595 IPython interactive namespace (because they remain in the namespace
596 where the profiler executes them).
596 where the profiler executes them).
597
597
598 Internally this triggers a call to %prun, see its documentation for
598 Internally this triggers a call to %prun, see its documentation for
599 details on the options available specifically for profiling.
599 details on the options available specifically for profiling.
600
600
601 There is one special usage for which the text above doesn't apply:
601 There is one special usage for which the text above doesn't apply:
602 if the filename ends with .ipy[nb], the file is run as ipython script,
602 if the filename ends with .ipy[nb], the file is run as ipython script,
603 just as if the commands were written on IPython prompt.
603 just as if the commands were written on IPython prompt.
604
604
605 -m
605 -m
606 specify module name to load instead of script path. Similar to
606 specify module name to load instead of script path. Similar to
607 the -m option for the python interpreter. Use this option last if you
607 the -m option for the python interpreter. Use this option last if you
608 want to combine with other %run options. Unlike the python interpreter
608 want to combine with other %run options. Unlike the python interpreter
609 only source modules are allowed no .pyc or .pyo files.
609 only source modules are allowed no .pyc or .pyo files.
610 For example::
610 For example::
611
611
612 %run -m example
612 %run -m example
613
613
614 will run the example module.
614 will run the example module.
615
615
616 -G
616 -G
617 disable shell-like glob expansion of arguments.
617 disable shell-like glob expansion of arguments.
618
618
619 """
619 """
620
620
621 # Logic to handle issue #3664
621 # Logic to handle issue #3664
622 # Add '--' after '-m <module_name>' to ignore additional args passed to a module.
622 # Add '--' after '-m <module_name>' to ignore additional args passed to a module.
623 if '-m' in parameter_s and '--' not in parameter_s:
623 if '-m' in parameter_s and '--' not in parameter_s:
624 argv = shlex.split(parameter_s, posix=(os.name == 'posix'))
624 argv = shlex.split(parameter_s, posix=(os.name == 'posix'))
625 for idx, arg in enumerate(argv):
625 for idx, arg in enumerate(argv):
626 if arg and arg.startswith('-') and arg != '-':
626 if arg and arg.startswith('-') and arg != '-':
627 if arg == '-m':
627 if arg == '-m':
628 argv.insert(idx + 2, '--')
628 argv.insert(idx + 2, '--')
629 break
629 break
630 else:
630 else:
631 # Positional arg, break
631 # Positional arg, break
632 break
632 break
633 parameter_s = ' '.join(shlex.quote(arg) for arg in argv)
633 parameter_s = ' '.join(shlex.quote(arg) for arg in argv)
634
634
635 # get arguments and set sys.argv for program to be run.
635 # get arguments and set sys.argv for program to be run.
636 opts, arg_lst = self.parse_options(parameter_s,
636 opts, arg_lst = self.parse_options(parameter_s,
637 'nidtN:b:pD:l:rs:T:em:G',
637 'nidtN:b:pD:l:rs:T:em:G',
638 mode='list', list_all=1)
638 mode='list', list_all=1)
639 if "m" in opts:
639 if "m" in opts:
640 modulename = opts["m"][0]
640 modulename = opts["m"][0]
641 modpath = find_mod(modulename)
641 modpath = find_mod(modulename)
642 if modpath is None:
642 if modpath is None:
643 warn('%r is not a valid modulename on sys.path'%modulename)
643 warn('%r is not a valid modulename on sys.path'%modulename)
644 return
644 return
645 arg_lst = [modpath] + arg_lst
645 arg_lst = [modpath] + arg_lst
646 try:
646 try:
647 filename = file_finder(arg_lst[0])
647 filename = file_finder(arg_lst[0])
648 except IndexError:
648 except IndexError:
649 warn('you must provide at least a filename.')
649 warn('you must provide at least a filename.')
650 print('\n%run:\n', oinspect.getdoc(self.run))
650 print('\n%run:\n', oinspect.getdoc(self.run))
651 return
651 return
652 except IOError as e:
652 except IOError as e:
653 try:
653 try:
654 msg = str(e)
654 msg = str(e)
655 except UnicodeError:
655 except UnicodeError:
656 msg = e.message
656 msg = e.message
657 error(msg)
657 error(msg)
658 return
658 return
659
659
660 if filename.lower().endswith(('.ipy', '.ipynb')):
660 if filename.lower().endswith(('.ipy', '.ipynb')):
661 with preserve_keys(self.shell.user_ns, '__file__'):
661 with preserve_keys(self.shell.user_ns, '__file__'):
662 self.shell.user_ns['__file__'] = filename
662 self.shell.user_ns['__file__'] = filename
663 self.shell.safe_execfile_ipy(filename)
663 self.shell.safe_execfile_ipy(filename)
664 return
664 return
665
665
666 # Control the response to exit() calls made by the script being run
666 # Control the response to exit() calls made by the script being run
667 exit_ignore = 'e' in opts
667 exit_ignore = 'e' in opts
668
668
669 # Make sure that the running script gets a proper sys.argv as if it
669 # Make sure that the running script gets a proper sys.argv as if it
670 # were run from a system shell.
670 # were run from a system shell.
671 save_argv = sys.argv # save it for later restoring
671 save_argv = sys.argv # save it for later restoring
672
672
673 if 'G' in opts:
673 if 'G' in opts:
674 args = arg_lst[1:]
674 args = arg_lst[1:]
675 else:
675 else:
676 # tilde and glob expansion
676 # tilde and glob expansion
677 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
677 args = shellglob(map(os.path.expanduser, arg_lst[1:]))
678
678
679 sys.argv = [filename] + args # put in the proper filename
679 sys.argv = [filename] + args # put in the proper filename
680
680
681 if 'n' in opts:
681 if 'n' in opts:
682 name = os.path.splitext(os.path.basename(filename))[0]
682 name = os.path.splitext(os.path.basename(filename))[0]
683 else:
683 else:
684 name = '__main__'
684 name = '__main__'
685
685
686 if 'i' in opts:
686 if 'i' in opts:
687 # Run in user's interactive namespace
687 # Run in user's interactive namespace
688 prog_ns = self.shell.user_ns
688 prog_ns = self.shell.user_ns
689 __name__save = self.shell.user_ns['__name__']
689 __name__save = self.shell.user_ns['__name__']
690 prog_ns['__name__'] = name
690 prog_ns['__name__'] = name
691 main_mod = self.shell.user_module
691 main_mod = self.shell.user_module
692
692
693 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
693 # Since '%run foo' emulates 'python foo.py' at the cmd line, we must
694 # set the __file__ global in the script's namespace
694 # set the __file__ global in the script's namespace
695 # TK: Is this necessary in interactive mode?
695 # TK: Is this necessary in interactive mode?
696 prog_ns['__file__'] = filename
696 prog_ns['__file__'] = filename
697 else:
697 else:
698 # Run in a fresh, empty namespace
698 # Run in a fresh, empty namespace
699
699
700 # The shell MUST hold a reference to prog_ns so after %run
700 # The shell MUST hold a reference to prog_ns so after %run
701 # exits, the python deletion mechanism doesn't zero it out
701 # exits, the python deletion mechanism doesn't zero it out
702 # (leaving dangling references). See interactiveshell for details
702 # (leaving dangling references). See interactiveshell for details
703 main_mod = self.shell.new_main_mod(filename, name)
703 main_mod = self.shell.new_main_mod(filename, name)
704 prog_ns = main_mod.__dict__
704 prog_ns = main_mod.__dict__
705
705
706 # pickle fix. See interactiveshell for an explanation. But we need to
706 # pickle fix. See interactiveshell for an explanation. But we need to
707 # make sure that, if we overwrite __main__, we replace it at the end
707 # make sure that, if we overwrite __main__, we replace it at the end
708 main_mod_name = prog_ns['__name__']
708 main_mod_name = prog_ns['__name__']
709
709
710 if main_mod_name == '__main__':
710 if main_mod_name == '__main__':
711 restore_main = sys.modules['__main__']
711 restore_main = sys.modules['__main__']
712 else:
712 else:
713 restore_main = False
713 restore_main = False
714
714
715 # This needs to be undone at the end to prevent holding references to
715 # This needs to be undone at the end to prevent holding references to
716 # every single object ever created.
716 # every single object ever created.
717 sys.modules[main_mod_name] = main_mod
717 sys.modules[main_mod_name] = main_mod
718
718
719 if 'p' in opts or 'd' in opts:
719 if 'p' in opts or 'd' in opts:
720 if 'm' in opts:
720 if 'm' in opts:
721 code = 'run_module(modulename, prog_ns)'
721 code = 'run_module(modulename, prog_ns)'
722 code_ns = {
722 code_ns = {
723 'run_module': self.shell.safe_run_module,
723 'run_module': self.shell.safe_run_module,
724 'prog_ns': prog_ns,
724 'prog_ns': prog_ns,
725 'modulename': modulename,
725 'modulename': modulename,
726 }
726 }
727 else:
727 else:
728 if 'd' in opts:
728 if 'd' in opts:
729 # allow exceptions to raise in debug mode
729 # allow exceptions to raise in debug mode
730 code = 'execfile(filename, prog_ns, raise_exceptions=True)'
730 code = 'execfile(filename, prog_ns, raise_exceptions=True)'
731 else:
731 else:
732 code = 'execfile(filename, prog_ns)'
732 code = 'execfile(filename, prog_ns)'
733 code_ns = {
733 code_ns = {
734 'execfile': self.shell.safe_execfile,
734 'execfile': self.shell.safe_execfile,
735 'prog_ns': prog_ns,
735 'prog_ns': prog_ns,
736 'filename': get_py_filename(filename),
736 'filename': get_py_filename(filename),
737 }
737 }
738
738
739 try:
739 try:
740 stats = None
740 stats = None
741 if 'p' in opts:
741 if 'p' in opts:
742 stats = self._run_with_profiler(code, opts, code_ns)
742 stats = self._run_with_profiler(code, opts, code_ns)
743 else:
743 else:
744 if 'd' in opts:
744 if 'd' in opts:
745 bp_file, bp_line = parse_breakpoint(
745 bp_file, bp_line = parse_breakpoint(
746 opts.get('b', ['1'])[0], filename)
746 opts.get('b', ['1'])[0], filename)
747 self._run_with_debugger(
747 self._run_with_debugger(
748 code, code_ns, filename, bp_line, bp_file)
748 code, code_ns, filename, bp_line, bp_file)
749 else:
749 else:
750 if 'm' in opts:
750 if 'm' in opts:
751 def run():
751 def run():
752 self.shell.safe_run_module(modulename, prog_ns)
752 self.shell.safe_run_module(modulename, prog_ns)
753 else:
753 else:
754 if runner is None:
754 if runner is None:
755 runner = self.default_runner
755 runner = self.default_runner
756 if runner is None:
756 if runner is None:
757 runner = self.shell.safe_execfile
757 runner = self.shell.safe_execfile
758
758
759 def run():
759 def run():
760 runner(filename, prog_ns, prog_ns,
760 runner(filename, prog_ns, prog_ns,
761 exit_ignore=exit_ignore)
761 exit_ignore=exit_ignore)
762
762
763 if 't' in opts:
763 if 't' in opts:
764 # timed execution
764 # timed execution
765 try:
765 try:
766 nruns = int(opts['N'][0])
766 nruns = int(opts['N'][0])
767 if nruns < 1:
767 if nruns < 1:
768 error('Number of runs must be >=1')
768 error('Number of runs must be >=1')
769 return
769 return
770 except (KeyError):
770 except (KeyError):
771 nruns = 1
771 nruns = 1
772 self._run_with_timing(run, nruns)
772 self._run_with_timing(run, nruns)
773 else:
773 else:
774 # regular execution
774 # regular execution
775 run()
775 run()
776
776
777 if 'i' in opts:
777 if 'i' in opts:
778 self.shell.user_ns['__name__'] = __name__save
778 self.shell.user_ns['__name__'] = __name__save
779 else:
779 else:
780 # update IPython interactive namespace
780 # update IPython interactive namespace
781
781
782 # Some forms of read errors on the file may mean the
782 # Some forms of read errors on the file may mean the
783 # __name__ key was never set; using pop we don't have to
783 # __name__ key was never set; using pop we don't have to
784 # worry about a possible KeyError.
784 # worry about a possible KeyError.
785 prog_ns.pop('__name__', None)
785 prog_ns.pop('__name__', None)
786
786
787 with preserve_keys(self.shell.user_ns, '__file__'):
787 with preserve_keys(self.shell.user_ns, '__file__'):
788 self.shell.user_ns.update(prog_ns)
788 self.shell.user_ns.update(prog_ns)
789 finally:
789 finally:
790 # It's a bit of a mystery why, but __builtins__ can change from
790 # It's a bit of a mystery why, but __builtins__ can change from
791 # being a module to becoming a dict missing some key data after
791 # being a module to becoming a dict missing some key data after
792 # %run. As best I can see, this is NOT something IPython is doing
792 # %run. As best I can see, this is NOT something IPython is doing
793 # at all, and similar problems have been reported before:
793 # at all, and similar problems have been reported before:
794 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
794 # http://coding.derkeiler.com/Archive/Python/comp.lang.python/2004-10/0188.html
795 # Since this seems to be done by the interpreter itself, the best
795 # Since this seems to be done by the interpreter itself, the best
796 # we can do is to at least restore __builtins__ for the user on
796 # we can do is to at least restore __builtins__ for the user on
797 # exit.
797 # exit.
798 self.shell.user_ns['__builtins__'] = builtin_mod
798 self.shell.user_ns['__builtins__'] = builtin_mod
799
799
800 # Ensure key global structures are restored
800 # Ensure key global structures are restored
801 sys.argv = save_argv
801 sys.argv = save_argv
802 if restore_main:
802 if restore_main:
803 sys.modules['__main__'] = restore_main
803 sys.modules['__main__'] = restore_main
804 else:
804 else:
805 # Remove from sys.modules the reference to main_mod we'd
805 # Remove from sys.modules the reference to main_mod we'd
806 # added. Otherwise it will trap references to objects
806 # added. Otherwise it will trap references to objects
807 # contained therein.
807 # contained therein.
808 del sys.modules[main_mod_name]
808 del sys.modules[main_mod_name]
809
809
810 return stats
810 return stats
811
811
812 def _run_with_debugger(self, code, code_ns, filename=None,
812 def _run_with_debugger(self, code, code_ns, filename=None,
813 bp_line=None, bp_file=None):
813 bp_line=None, bp_file=None):
814 """
814 """
815 Run `code` in debugger with a break point.
815 Run `code` in debugger with a break point.
816
816
817 Parameters
817 Parameters
818 ----------
818 ----------
819 code : str
819 code : str
820 Code to execute.
820 Code to execute.
821 code_ns : dict
821 code_ns : dict
822 A namespace in which `code` is executed.
822 A namespace in which `code` is executed.
823 filename : str
823 filename : str
824 `code` is ran as if it is in `filename`.
824 `code` is ran as if it is in `filename`.
825 bp_line : int, optional
825 bp_line : int, optional
826 Line number of the break point.
826 Line number of the break point.
827 bp_file : str, optional
827 bp_file : str, optional
828 Path to the file in which break point is specified.
828 Path to the file in which break point is specified.
829 `filename` is used if not given.
829 `filename` is used if not given.
830
830
831 Raises
831 Raises
832 ------
832 ------
833 UsageError
833 UsageError
834 If the break point given by `bp_line` is not valid.
834 If the break point given by `bp_line` is not valid.
835
835
836 """
836 """
837 deb = self.shell.InteractiveTB.pdb
837 deb = self.shell.InteractiveTB.pdb
838 if not deb:
838 if not deb:
839 self.shell.InteractiveTB.pdb = self.shell.InteractiveTB.debugger_cls()
839 self.shell.InteractiveTB.pdb = self.shell.InteractiveTB.debugger_cls()
840 deb = self.shell.InteractiveTB.pdb
840 deb = self.shell.InteractiveTB.pdb
841
841
842 # deb.checkline() fails if deb.curframe exists but is None; it can
842 # deb.checkline() fails if deb.curframe exists but is None; it can
843 # handle it not existing. https://github.com/ipython/ipython/issues/10028
843 # handle it not existing. https://github.com/ipython/ipython/issues/10028
844 if hasattr(deb, 'curframe'):
844 if hasattr(deb, 'curframe'):
845 del deb.curframe
845 del deb.curframe
846
846
847 # reset Breakpoint state, which is moronically kept
847 # reset Breakpoint state, which is moronically kept
848 # in a class
848 # in a class
849 bdb.Breakpoint.next = 1
849 bdb.Breakpoint.next = 1
850 bdb.Breakpoint.bplist = {}
850 bdb.Breakpoint.bplist = {}
851 bdb.Breakpoint.bpbynumber = [None]
851 bdb.Breakpoint.bpbynumber = [None]
852 deb.clear_all_breaks()
852 deb.clear_all_breaks()
853 if bp_line is not None:
853 if bp_line is not None:
854 # Set an initial breakpoint to stop execution
854 # Set an initial breakpoint to stop execution
855 maxtries = 10
855 maxtries = 10
856 bp_file = bp_file or filename
856 bp_file = bp_file or filename
857 checkline = deb.checkline(bp_file, bp_line)
857 checkline = deb.checkline(bp_file, bp_line)
858 if not checkline:
858 if not checkline:
859 for bp in range(bp_line + 1, bp_line + maxtries + 1):
859 for bp in range(bp_line + 1, bp_line + maxtries + 1):
860 if deb.checkline(bp_file, bp):
860 if deb.checkline(bp_file, bp):
861 break
861 break
862 else:
862 else:
863 msg = ("\nI failed to find a valid line to set "
863 msg = ("\nI failed to find a valid line to set "
864 "a breakpoint\n"
864 "a breakpoint\n"
865 "after trying up to line: %s.\n"
865 "after trying up to line: %s.\n"
866 "Please set a valid breakpoint manually "
866 "Please set a valid breakpoint manually "
867 "with the -b option." % bp)
867 "with the -b option." % bp)
868 raise UsageError(msg)
868 raise UsageError(msg)
869 # if we find a good linenumber, set the breakpoint
869 # if we find a good linenumber, set the breakpoint
870 deb.do_break('%s:%s' % (bp_file, bp_line))
870 deb.do_break('%s:%s' % (bp_file, bp_line))
871
871
872 if filename:
872 if filename:
873 # Mimic Pdb._runscript(...)
873 # Mimic Pdb._runscript(...)
874 deb._wait_for_mainpyfile = True
874 deb._wait_for_mainpyfile = True
875 deb.mainpyfile = deb.canonic(filename)
875 deb.mainpyfile = deb.canonic(filename)
876
876
877 # Start file run
877 # Start file run
878 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
878 print("NOTE: Enter 'c' at the %s prompt to continue execution." % deb.prompt)
879 try:
879 try:
880 if filename:
880 if filename:
881 # save filename so it can be used by methods on the deb object
881 # save filename so it can be used by methods on the deb object
882 deb._exec_filename = filename
882 deb._exec_filename = filename
883 while True:
883 while True:
884 try:
884 try:
885 deb.run(code, code_ns)
885 deb.run(code, code_ns)
886 except Restart:
886 except Restart:
887 print("Restarting")
887 print("Restarting")
888 if filename:
888 if filename:
889 deb._wait_for_mainpyfile = True
889 deb._wait_for_mainpyfile = True
890 deb.mainpyfile = deb.canonic(filename)
890 deb.mainpyfile = deb.canonic(filename)
891 continue
891 continue
892 else:
892 else:
893 break
893 break
894
894
895
895
896 except:
896 except:
897 etype, value, tb = sys.exc_info()
897 etype, value, tb = sys.exc_info()
898 # Skip three frames in the traceback: the %run one,
898 # Skip three frames in the traceback: the %run one,
899 # one inside bdb.py, and the command-line typed by the
899 # one inside bdb.py, and the command-line typed by the
900 # user (run by exec in pdb itself).
900 # user (run by exec in pdb itself).
901 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
901 self.shell.InteractiveTB(etype, value, tb, tb_offset=3)
902
902
903 @staticmethod
903 @staticmethod
904 def _run_with_timing(run, nruns):
904 def _run_with_timing(run, nruns):
905 """
905 """
906 Run function `run` and print timing information.
906 Run function `run` and print timing information.
907
907
908 Parameters
908 Parameters
909 ----------
909 ----------
910 run : callable
910 run : callable
911 Any callable object which takes no argument.
911 Any callable object which takes no argument.
912 nruns : int
912 nruns : int
913 Number of times to execute `run`.
913 Number of times to execute `run`.
914
914
915 """
915 """
916 twall0 = time.time()
916 twall0 = time.time()
917 if nruns == 1:
917 if nruns == 1:
918 t0 = clock2()
918 t0 = clock2()
919 run()
919 run()
920 t1 = clock2()
920 t1 = clock2()
921 t_usr = t1[0] - t0[0]
921 t_usr = t1[0] - t0[0]
922 t_sys = t1[1] - t0[1]
922 t_sys = t1[1] - t0[1]
923 print("\nIPython CPU timings (estimated):")
923 print("\nIPython CPU timings (estimated):")
924 print(" User : %10.2f s." % t_usr)
924 print(" User : %10.2f s." % t_usr)
925 print(" System : %10.2f s." % t_sys)
925 print(" System : %10.2f s." % t_sys)
926 else:
926 else:
927 runs = range(nruns)
927 runs = range(nruns)
928 t0 = clock2()
928 t0 = clock2()
929 for nr in runs:
929 for nr in runs:
930 run()
930 run()
931 t1 = clock2()
931 t1 = clock2()
932 t_usr = t1[0] - t0[0]
932 t_usr = t1[0] - t0[0]
933 t_sys = t1[1] - t0[1]
933 t_sys = t1[1] - t0[1]
934 print("\nIPython CPU timings (estimated):")
934 print("\nIPython CPU timings (estimated):")
935 print("Total runs performed:", nruns)
935 print("Total runs performed:", nruns)
936 print(" Times : %10s %10s" % ('Total', 'Per run'))
936 print(" Times : %10s %10s" % ('Total', 'Per run'))
937 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
937 print(" User : %10.2f s, %10.2f s." % (t_usr, t_usr / nruns))
938 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
938 print(" System : %10.2f s, %10.2f s." % (t_sys, t_sys / nruns))
939 twall1 = time.time()
939 twall1 = time.time()
940 print("Wall time: %10.2f s." % (twall1 - twall0))
940 print("Wall time: %10.2f s." % (twall1 - twall0))
941
941
942 @skip_doctest
942 @skip_doctest
943 @line_cell_magic
943 @line_cell_magic
944 @needs_local_scope
944 @needs_local_scope
945 def timeit(self, line='', cell=None, local_ns=None):
945 def timeit(self, line='', cell=None, local_ns=None):
946 """Time execution of a Python statement or expression
946 """Time execution of a Python statement or expression
947
947
948 Usage, in line mode:
948 Usage, in line mode:
949 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
949 %timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] statement
950 or in cell mode:
950 or in cell mode:
951 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
951 %%timeit [-n<N> -r<R> [-t|-c] -q -p<P> -o] setup_code
952 code
952 code
953 code...
953 code...
954
954
955 Time execution of a Python statement or expression using the timeit
955 Time execution of a Python statement or expression using the timeit
956 module. This function can be used both as a line and cell magic:
956 module. This function can be used both as a line and cell magic:
957
957
958 - In line mode you can time a single-line statement (though multiple
958 - In line mode you can time a single-line statement (though multiple
959 ones can be chained with using semicolons).
959 ones can be chained with using semicolons).
960
960
961 - In cell mode, the statement in the first line is used as setup code
961 - In cell mode, the statement in the first line is used as setup code
962 (executed but not timed) and the body of the cell is timed. The cell
962 (executed but not timed) and the body of the cell is timed. The cell
963 body has access to any variables created in the setup code.
963 body has access to any variables created in the setup code.
964
964
965 Options:
965 Options:
966 -n<N>: execute the given statement <N> times in a loop. If this value
966 -n<N>: execute the given statement <N> times in a loop. If this value
967 is not given, a fitting value is chosen.
967 is not given, a fitting value is chosen.
968
968
969 -r<R>: repeat the loop iteration <R> times and take the best result.
969 -r<R>: repeat the loop iteration <R> times and take the best result.
970 Default: 3
970 Default: 3
971
971
972 -t: use time.time to measure the time, which is the default on Unix.
972 -t: use time.time to measure the time, which is the default on Unix.
973 This function measures wall time.
973 This function measures wall time.
974
974
975 -c: use time.clock to measure the time, which is the default on
975 -c: use time.clock to measure the time, which is the default on
976 Windows and measures wall time. On Unix, resource.getrusage is used
976 Windows and measures wall time. On Unix, resource.getrusage is used
977 instead and returns the CPU user time.
977 instead and returns the CPU user time.
978
978
979 -p<P>: use a precision of <P> digits to display the timing result.
979 -p<P>: use a precision of <P> digits to display the timing result.
980 Default: 3
980 Default: 3
981
981
982 -q: Quiet, do not print result.
982 -q: Quiet, do not print result.
983
983
984 -o: return a TimeitResult that can be stored in a variable to inspect
984 -o: return a TimeitResult that can be stored in a variable to inspect
985 the result in more details.
985 the result in more details.
986
986
987
987
988 Examples
988 Examples
989 --------
989 --------
990 ::
990 ::
991
991
992 In [1]: %timeit pass
992 In [1]: %timeit pass
993 8.26 ns Β± 0.12 ns per loop (mean Β± std. dev. of 7 runs, 100000000 loops each)
993 8.26 ns Β± 0.12 ns per loop (mean Β± std. dev. of 7 runs, 100000000 loops each)
994
994
995 In [2]: u = None
995 In [2]: u = None
996
996
997 In [3]: %timeit u is None
997 In [3]: %timeit u is None
998 29.9 ns Β± 0.643 ns per loop (mean Β± std. dev. of 7 runs, 10000000 loops each)
998 29.9 ns Β± 0.643 ns per loop (mean Β± std. dev. of 7 runs, 10000000 loops each)
999
999
1000 In [4]: %timeit -r 4 u == None
1000 In [4]: %timeit -r 4 u == None
1001
1001
1002 In [5]: import time
1002 In [5]: import time
1003
1003
1004 In [6]: %timeit -n1 time.sleep(2)
1004 In [6]: %timeit -n1 time.sleep(2)
1005
1005
1006
1006
1007 The times reported by %timeit will be slightly higher than those
1007 The times reported by %timeit will be slightly higher than those
1008 reported by the timeit.py script when variables are accessed. This is
1008 reported by the timeit.py script when variables are accessed. This is
1009 due to the fact that %timeit executes the statement in the namespace
1009 due to the fact that %timeit executes the statement in the namespace
1010 of the shell, compared with timeit.py, which uses a single setup
1010 of the shell, compared with timeit.py, which uses a single setup
1011 statement to import function or create variables. Generally, the bias
1011 statement to import function or create variables. Generally, the bias
1012 does not matter as long as results from timeit.py are not mixed with
1012 does not matter as long as results from timeit.py are not mixed with
1013 those from %timeit."""
1013 those from %timeit."""
1014
1014
1015 opts, stmt = self.parse_options(line,'n:r:tcp:qo',
1015 opts, stmt = self.parse_options(line,'n:r:tcp:qo',
1016 posix=False, strict=False)
1016 posix=False, strict=False)
1017 if stmt == "" and cell is None:
1017 if stmt == "" and cell is None:
1018 return
1018 return
1019
1019
1020 timefunc = timeit.default_timer
1020 timefunc = timeit.default_timer
1021 number = int(getattr(opts, "n", 0))
1021 number = int(getattr(opts, "n", 0))
1022 default_repeat = 7 if timeit.default_repeat < 7 else timeit.default_repeat
1022 default_repeat = 7 if timeit.default_repeat < 7 else timeit.default_repeat
1023 repeat = int(getattr(opts, "r", default_repeat))
1023 repeat = int(getattr(opts, "r", default_repeat))
1024 precision = int(getattr(opts, "p", 3))
1024 precision = int(getattr(opts, "p", 3))
1025 quiet = 'q' in opts
1025 quiet = 'q' in opts
1026 return_result = 'o' in opts
1026 return_result = 'o' in opts
1027 if hasattr(opts, "t"):
1027 if hasattr(opts, "t"):
1028 timefunc = time.time
1028 timefunc = time.time
1029 if hasattr(opts, "c"):
1029 if hasattr(opts, "c"):
1030 timefunc = clock
1030 timefunc = clock
1031
1031
1032 timer = Timer(timer=timefunc)
1032 timer = Timer(timer=timefunc)
1033 # this code has tight coupling to the inner workings of timeit.Timer,
1033 # this code has tight coupling to the inner workings of timeit.Timer,
1034 # but is there a better way to achieve that the code stmt has access
1034 # but is there a better way to achieve that the code stmt has access
1035 # to the shell namespace?
1035 # to the shell namespace?
1036 transform = self.shell.input_splitter.transform_cell
1036 transform = self.shell.input_transformer_manager.transform_cell
1037
1037
1038 if cell is None:
1038 if cell is None:
1039 # called as line magic
1039 # called as line magic
1040 ast_setup = self.shell.compile.ast_parse("pass")
1040 ast_setup = self.shell.compile.ast_parse("pass")
1041 ast_stmt = self.shell.compile.ast_parse(transform(stmt))
1041 ast_stmt = self.shell.compile.ast_parse(transform(stmt))
1042 else:
1042 else:
1043 ast_setup = self.shell.compile.ast_parse(transform(stmt))
1043 ast_setup = self.shell.compile.ast_parse(transform(stmt))
1044 ast_stmt = self.shell.compile.ast_parse(transform(cell))
1044 ast_stmt = self.shell.compile.ast_parse(transform(cell))
1045
1045
1046 ast_setup = self.shell.transform_ast(ast_setup)
1046 ast_setup = self.shell.transform_ast(ast_setup)
1047 ast_stmt = self.shell.transform_ast(ast_stmt)
1047 ast_stmt = self.shell.transform_ast(ast_stmt)
1048
1048
1049 # Check that these compile to valid Python code *outside* the timer func
1049 # Check that these compile to valid Python code *outside* the timer func
1050 # Invalid code may become valid when put inside the function & loop,
1050 # Invalid code may become valid when put inside the function & loop,
1051 # which messes up error messages.
1051 # which messes up error messages.
1052 # https://github.com/ipython/ipython/issues/10636
1052 # https://github.com/ipython/ipython/issues/10636
1053 self.shell.compile(ast_setup, "<magic-timeit-setup>", "exec")
1053 self.shell.compile(ast_setup, "<magic-timeit-setup>", "exec")
1054 self.shell.compile(ast_stmt, "<magic-timeit-stmt>", "exec")
1054 self.shell.compile(ast_stmt, "<magic-timeit-stmt>", "exec")
1055
1055
1056 # This codestring is taken from timeit.template - we fill it in as an
1056 # This codestring is taken from timeit.template - we fill it in as an
1057 # AST, so that we can apply our AST transformations to the user code
1057 # AST, so that we can apply our AST transformations to the user code
1058 # without affecting the timing code.
1058 # without affecting the timing code.
1059 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
1059 timeit_ast_template = ast.parse('def inner(_it, _timer):\n'
1060 ' setup\n'
1060 ' setup\n'
1061 ' _t0 = _timer()\n'
1061 ' _t0 = _timer()\n'
1062 ' for _i in _it:\n'
1062 ' for _i in _it:\n'
1063 ' stmt\n'
1063 ' stmt\n'
1064 ' _t1 = _timer()\n'
1064 ' _t1 = _timer()\n'
1065 ' return _t1 - _t0\n')
1065 ' return _t1 - _t0\n')
1066
1066
1067 timeit_ast = TimeitTemplateFiller(ast_setup, ast_stmt).visit(timeit_ast_template)
1067 timeit_ast = TimeitTemplateFiller(ast_setup, ast_stmt).visit(timeit_ast_template)
1068 timeit_ast = ast.fix_missing_locations(timeit_ast)
1068 timeit_ast = ast.fix_missing_locations(timeit_ast)
1069
1069
1070 # Track compilation time so it can be reported if too long
1070 # Track compilation time so it can be reported if too long
1071 # Minimum time above which compilation time will be reported
1071 # Minimum time above which compilation time will be reported
1072 tc_min = 0.1
1072 tc_min = 0.1
1073
1073
1074 t0 = clock()
1074 t0 = clock()
1075 code = self.shell.compile(timeit_ast, "<magic-timeit>", "exec")
1075 code = self.shell.compile(timeit_ast, "<magic-timeit>", "exec")
1076 tc = clock()-t0
1076 tc = clock()-t0
1077
1077
1078 ns = {}
1078 ns = {}
1079 glob = self.shell.user_ns
1079 glob = self.shell.user_ns
1080 # handles global vars with same name as local vars. We store them in conflict_globs.
1080 # handles global vars with same name as local vars. We store them in conflict_globs.
1081 if local_ns is not None:
1081 if local_ns is not None:
1082 conflict_globs = {}
1082 conflict_globs = {}
1083 for var_name, var_val in glob.items():
1083 for var_name, var_val in glob.items():
1084 if var_name in local_ns:
1084 if var_name in local_ns:
1085 conflict_globs[var_name] = var_val
1085 conflict_globs[var_name] = var_val
1086 glob.update(local_ns)
1086 glob.update(local_ns)
1087
1087
1088 exec(code, glob, ns)
1088 exec(code, glob, ns)
1089 timer.inner = ns["inner"]
1089 timer.inner = ns["inner"]
1090
1090
1091 # This is used to check if there is a huge difference between the
1091 # This is used to check if there is a huge difference between the
1092 # best and worst timings.
1092 # best and worst timings.
1093 # Issue: https://github.com/ipython/ipython/issues/6471
1093 # Issue: https://github.com/ipython/ipython/issues/6471
1094 if number == 0:
1094 if number == 0:
1095 # determine number so that 0.2 <= total time < 2.0
1095 # determine number so that 0.2 <= total time < 2.0
1096 for index in range(0, 10):
1096 for index in range(0, 10):
1097 number = 10 ** index
1097 number = 10 ** index
1098 time_number = timer.timeit(number)
1098 time_number = timer.timeit(number)
1099 if time_number >= 0.2:
1099 if time_number >= 0.2:
1100 break
1100 break
1101
1101
1102 all_runs = timer.repeat(repeat, number)
1102 all_runs = timer.repeat(repeat, number)
1103 best = min(all_runs) / number
1103 best = min(all_runs) / number
1104 worst = max(all_runs) / number
1104 worst = max(all_runs) / number
1105 timeit_result = TimeitResult(number, repeat, best, worst, all_runs, tc, precision)
1105 timeit_result = TimeitResult(number, repeat, best, worst, all_runs, tc, precision)
1106
1106
1107 # Restore global vars from conflict_globs
1107 # Restore global vars from conflict_globs
1108 if local_ns is not None:
1108 if local_ns is not None:
1109 if len(conflict_globs) > 0:
1109 if len(conflict_globs) > 0:
1110 glob.update(conflict_globs)
1110 glob.update(conflict_globs)
1111
1111
1112 if not quiet :
1112 if not quiet :
1113 # Check best timing is greater than zero to avoid a
1113 # Check best timing is greater than zero to avoid a
1114 # ZeroDivisionError.
1114 # ZeroDivisionError.
1115 # In cases where the slowest timing is lesser than a micosecond
1115 # In cases where the slowest timing is lesser than a micosecond
1116 # we assume that it does not really matter if the fastest
1116 # we assume that it does not really matter if the fastest
1117 # timing is 4 times faster than the slowest timing or not.
1117 # timing is 4 times faster than the slowest timing or not.
1118 if worst > 4 * best and best > 0 and worst > 1e-6:
1118 if worst > 4 * best and best > 0 and worst > 1e-6:
1119 print("The slowest run took %0.2f times longer than the "
1119 print("The slowest run took %0.2f times longer than the "
1120 "fastest. This could mean that an intermediate result "
1120 "fastest. This could mean that an intermediate result "
1121 "is being cached." % (worst / best))
1121 "is being cached." % (worst / best))
1122
1122
1123 print( timeit_result )
1123 print( timeit_result )
1124
1124
1125 if tc > tc_min:
1125 if tc > tc_min:
1126 print("Compiler time: %.2f s" % tc)
1126 print("Compiler time: %.2f s" % tc)
1127 if return_result:
1127 if return_result:
1128 return timeit_result
1128 return timeit_result
1129
1129
1130 @skip_doctest
1130 @skip_doctest
1131 @needs_local_scope
1131 @needs_local_scope
1132 @line_cell_magic
1132 @line_cell_magic
1133 def time(self,line='', cell=None, local_ns=None):
1133 def time(self,line='', cell=None, local_ns=None):
1134 """Time execution of a Python statement or expression.
1134 """Time execution of a Python statement or expression.
1135
1135
1136 The CPU and wall clock times are printed, and the value of the
1136 The CPU and wall clock times are printed, and the value of the
1137 expression (if any) is returned. Note that under Win32, system time
1137 expression (if any) is returned. Note that under Win32, system time
1138 is always reported as 0, since it can not be measured.
1138 is always reported as 0, since it can not be measured.
1139
1139
1140 This function can be used both as a line and cell magic:
1140 This function can be used both as a line and cell magic:
1141
1141
1142 - In line mode you can time a single-line statement (though multiple
1142 - In line mode you can time a single-line statement (though multiple
1143 ones can be chained with using semicolons).
1143 ones can be chained with using semicolons).
1144
1144
1145 - In cell mode, you can time the cell body (a directly
1145 - In cell mode, you can time the cell body (a directly
1146 following statement raises an error).
1146 following statement raises an error).
1147
1147
1148 This function provides very basic timing functionality. Use the timeit
1148 This function provides very basic timing functionality. Use the timeit
1149 magic for more control over the measurement.
1149 magic for more control over the measurement.
1150
1150
1151 Examples
1151 Examples
1152 --------
1152 --------
1153 ::
1153 ::
1154
1154
1155 In [1]: %time 2**128
1155 In [1]: %time 2**128
1156 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1156 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1157 Wall time: 0.00
1157 Wall time: 0.00
1158 Out[1]: 340282366920938463463374607431768211456L
1158 Out[1]: 340282366920938463463374607431768211456L
1159
1159
1160 In [2]: n = 1000000
1160 In [2]: n = 1000000
1161
1161
1162 In [3]: %time sum(range(n))
1162 In [3]: %time sum(range(n))
1163 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1163 CPU times: user 1.20 s, sys: 0.05 s, total: 1.25 s
1164 Wall time: 1.37
1164 Wall time: 1.37
1165 Out[3]: 499999500000L
1165 Out[3]: 499999500000L
1166
1166
1167 In [4]: %time print 'hello world'
1167 In [4]: %time print 'hello world'
1168 hello world
1168 hello world
1169 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1169 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1170 Wall time: 0.00
1170 Wall time: 0.00
1171
1171
1172 Note that the time needed by Python to compile the given expression
1172 Note that the time needed by Python to compile the given expression
1173 will be reported if it is more than 0.1s. In this example, the
1173 will be reported if it is more than 0.1s. In this example, the
1174 actual exponentiation is done by Python at compilation time, so while
1174 actual exponentiation is done by Python at compilation time, so while
1175 the expression can take a noticeable amount of time to compute, that
1175 the expression can take a noticeable amount of time to compute, that
1176 time is purely due to the compilation:
1176 time is purely due to the compilation:
1177
1177
1178 In [5]: %time 3**9999;
1178 In [5]: %time 3**9999;
1179 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1179 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1180 Wall time: 0.00 s
1180 Wall time: 0.00 s
1181
1181
1182 In [6]: %time 3**999999;
1182 In [6]: %time 3**999999;
1183 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1183 CPU times: user 0.00 s, sys: 0.00 s, total: 0.00 s
1184 Wall time: 0.00 s
1184 Wall time: 0.00 s
1185 Compiler : 0.78 s
1185 Compiler : 0.78 s
1186 """
1186 """
1187
1187
1188 # fail immediately if the given expression can't be compiled
1188 # fail immediately if the given expression can't be compiled
1189
1189
1190 if line and cell:
1190 if line and cell:
1191 raise UsageError("Can't use statement directly after '%%time'!")
1191 raise UsageError("Can't use statement directly after '%%time'!")
1192
1192
1193 if cell:
1193 if cell:
1194 expr = self.shell.input_transformer_manager.transform_cell(cell)
1194 expr = self.shell.input_transformer_manager.transform_cell(cell)
1195 else:
1195 else:
1196 expr = self.shell.input_transformer_manager.transform_cell(line)
1196 expr = self.shell.input_transformer_manager.transform_cell(line)
1197
1197
1198 # Minimum time above which parse time will be reported
1198 # Minimum time above which parse time will be reported
1199 tp_min = 0.1
1199 tp_min = 0.1
1200
1200
1201 t0 = clock()
1201 t0 = clock()
1202 expr_ast = self.shell.compile.ast_parse(expr)
1202 expr_ast = self.shell.compile.ast_parse(expr)
1203 tp = clock()-t0
1203 tp = clock()-t0
1204
1204
1205 # Apply AST transformations
1205 # Apply AST transformations
1206 expr_ast = self.shell.transform_ast(expr_ast)
1206 expr_ast = self.shell.transform_ast(expr_ast)
1207
1207
1208 # Minimum time above which compilation time will be reported
1208 # Minimum time above which compilation time will be reported
1209 tc_min = 0.1
1209 tc_min = 0.1
1210
1210
1211 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1211 if len(expr_ast.body)==1 and isinstance(expr_ast.body[0], ast.Expr):
1212 mode = 'eval'
1212 mode = 'eval'
1213 source = '<timed eval>'
1213 source = '<timed eval>'
1214 expr_ast = ast.Expression(expr_ast.body[0].value)
1214 expr_ast = ast.Expression(expr_ast.body[0].value)
1215 else:
1215 else:
1216 mode = 'exec'
1216 mode = 'exec'
1217 source = '<timed exec>'
1217 source = '<timed exec>'
1218 t0 = clock()
1218 t0 = clock()
1219 code = self.shell.compile(expr_ast, source, mode)
1219 code = self.shell.compile(expr_ast, source, mode)
1220 tc = clock()-t0
1220 tc = clock()-t0
1221
1221
1222 # skew measurement as little as possible
1222 # skew measurement as little as possible
1223 glob = self.shell.user_ns
1223 glob = self.shell.user_ns
1224 wtime = time.time
1224 wtime = time.time
1225 # time execution
1225 # time execution
1226 wall_st = wtime()
1226 wall_st = wtime()
1227 if mode=='eval':
1227 if mode=='eval':
1228 st = clock2()
1228 st = clock2()
1229 try:
1229 try:
1230 out = eval(code, glob, local_ns)
1230 out = eval(code, glob, local_ns)
1231 except:
1231 except:
1232 self.shell.showtraceback()
1232 self.shell.showtraceback()
1233 return
1233 return
1234 end = clock2()
1234 end = clock2()
1235 else:
1235 else:
1236 st = clock2()
1236 st = clock2()
1237 try:
1237 try:
1238 exec(code, glob, local_ns)
1238 exec(code, glob, local_ns)
1239 except:
1239 except:
1240 self.shell.showtraceback()
1240 self.shell.showtraceback()
1241 return
1241 return
1242 end = clock2()
1242 end = clock2()
1243 out = None
1243 out = None
1244 wall_end = wtime()
1244 wall_end = wtime()
1245 # Compute actual times and report
1245 # Compute actual times and report
1246 wall_time = wall_end-wall_st
1246 wall_time = wall_end-wall_st
1247 cpu_user = end[0]-st[0]
1247 cpu_user = end[0]-st[0]
1248 cpu_sys = end[1]-st[1]
1248 cpu_sys = end[1]-st[1]
1249 cpu_tot = cpu_user+cpu_sys
1249 cpu_tot = cpu_user+cpu_sys
1250 # On windows cpu_sys is always zero, so no new information to the next print
1250 # On windows cpu_sys is always zero, so no new information to the next print
1251 if sys.platform != 'win32':
1251 if sys.platform != 'win32':
1252 print("CPU times: user %s, sys: %s, total: %s" % \
1252 print("CPU times: user %s, sys: %s, total: %s" % \
1253 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1253 (_format_time(cpu_user),_format_time(cpu_sys),_format_time(cpu_tot)))
1254 print("Wall time: %s" % _format_time(wall_time))
1254 print("Wall time: %s" % _format_time(wall_time))
1255 if tc > tc_min:
1255 if tc > tc_min:
1256 print("Compiler : %s" % _format_time(tc))
1256 print("Compiler : %s" % _format_time(tc))
1257 if tp > tp_min:
1257 if tp > tp_min:
1258 print("Parser : %s" % _format_time(tp))
1258 print("Parser : %s" % _format_time(tp))
1259 return out
1259 return out
1260
1260
1261 @skip_doctest
1261 @skip_doctest
1262 @line_magic
1262 @line_magic
1263 def macro(self, parameter_s=''):
1263 def macro(self, parameter_s=''):
1264 """Define a macro for future re-execution. It accepts ranges of history,
1264 """Define a macro for future re-execution. It accepts ranges of history,
1265 filenames or string objects.
1265 filenames or string objects.
1266
1266
1267 Usage:\\
1267 Usage:\\
1268 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1268 %macro [options] name n1-n2 n3-n4 ... n5 .. n6 ...
1269
1269
1270 Options:
1270 Options:
1271
1271
1272 -r: use 'raw' input. By default, the 'processed' history is used,
1272 -r: use 'raw' input. By default, the 'processed' history is used,
1273 so that magics are loaded in their transformed version to valid
1273 so that magics are loaded in their transformed version to valid
1274 Python. If this option is given, the raw input as typed at the
1274 Python. If this option is given, the raw input as typed at the
1275 command line is used instead.
1275 command line is used instead.
1276
1276
1277 -q: quiet macro definition. By default, a tag line is printed
1277 -q: quiet macro definition. By default, a tag line is printed
1278 to indicate the macro has been created, and then the contents of
1278 to indicate the macro has been created, and then the contents of
1279 the macro are printed. If this option is given, then no printout
1279 the macro are printed. If this option is given, then no printout
1280 is produced once the macro is created.
1280 is produced once the macro is created.
1281
1281
1282 This will define a global variable called `name` which is a string
1282 This will define a global variable called `name` which is a string
1283 made of joining the slices and lines you specify (n1,n2,... numbers
1283 made of joining the slices and lines you specify (n1,n2,... numbers
1284 above) from your input history into a single string. This variable
1284 above) from your input history into a single string. This variable
1285 acts like an automatic function which re-executes those lines as if
1285 acts like an automatic function which re-executes those lines as if
1286 you had typed them. You just type 'name' at the prompt and the code
1286 you had typed them. You just type 'name' at the prompt and the code
1287 executes.
1287 executes.
1288
1288
1289 The syntax for indicating input ranges is described in %history.
1289 The syntax for indicating input ranges is described in %history.
1290
1290
1291 Note: as a 'hidden' feature, you can also use traditional python slice
1291 Note: as a 'hidden' feature, you can also use traditional python slice
1292 notation, where N:M means numbers N through M-1.
1292 notation, where N:M means numbers N through M-1.
1293
1293
1294 For example, if your history contains (print using %hist -n )::
1294 For example, if your history contains (print using %hist -n )::
1295
1295
1296 44: x=1
1296 44: x=1
1297 45: y=3
1297 45: y=3
1298 46: z=x+y
1298 46: z=x+y
1299 47: print x
1299 47: print x
1300 48: a=5
1300 48: a=5
1301 49: print 'x',x,'y',y
1301 49: print 'x',x,'y',y
1302
1302
1303 you can create a macro with lines 44 through 47 (included) and line 49
1303 you can create a macro with lines 44 through 47 (included) and line 49
1304 called my_macro with::
1304 called my_macro with::
1305
1305
1306 In [55]: %macro my_macro 44-47 49
1306 In [55]: %macro my_macro 44-47 49
1307
1307
1308 Now, typing `my_macro` (without quotes) will re-execute all this code
1308 Now, typing `my_macro` (without quotes) will re-execute all this code
1309 in one pass.
1309 in one pass.
1310
1310
1311 You don't need to give the line-numbers in order, and any given line
1311 You don't need to give the line-numbers in order, and any given line
1312 number can appear multiple times. You can assemble macros with any
1312 number can appear multiple times. You can assemble macros with any
1313 lines from your input history in any order.
1313 lines from your input history in any order.
1314
1314
1315 The macro is a simple object which holds its value in an attribute,
1315 The macro is a simple object which holds its value in an attribute,
1316 but IPython's display system checks for macros and executes them as
1316 but IPython's display system checks for macros and executes them as
1317 code instead of printing them when you type their name.
1317 code instead of printing them when you type their name.
1318
1318
1319 You can view a macro's contents by explicitly printing it with::
1319 You can view a macro's contents by explicitly printing it with::
1320
1320
1321 print macro_name
1321 print macro_name
1322
1322
1323 """
1323 """
1324 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1324 opts,args = self.parse_options(parameter_s,'rq',mode='list')
1325 if not args: # List existing macros
1325 if not args: # List existing macros
1326 return sorted(k for k,v in self.shell.user_ns.items() if isinstance(v, Macro))
1326 return sorted(k for k,v in self.shell.user_ns.items() if isinstance(v, Macro))
1327 if len(args) == 1:
1327 if len(args) == 1:
1328 raise UsageError(
1328 raise UsageError(
1329 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1329 "%macro insufficient args; usage '%macro name n1-n2 n3-4...")
1330 name, codefrom = args[0], " ".join(args[1:])
1330 name, codefrom = args[0], " ".join(args[1:])
1331
1331
1332 #print 'rng',ranges # dbg
1332 #print 'rng',ranges # dbg
1333 try:
1333 try:
1334 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1334 lines = self.shell.find_user_code(codefrom, 'r' in opts)
1335 except (ValueError, TypeError) as e:
1335 except (ValueError, TypeError) as e:
1336 print(e.args[0])
1336 print(e.args[0])
1337 return
1337 return
1338 macro = Macro(lines)
1338 macro = Macro(lines)
1339 self.shell.define_macro(name, macro)
1339 self.shell.define_macro(name, macro)
1340 if not ( 'q' in opts) :
1340 if not ( 'q' in opts) :
1341 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1341 print('Macro `%s` created. To execute, type its name (without quotes).' % name)
1342 print('=== Macro contents: ===')
1342 print('=== Macro contents: ===')
1343 print(macro, end=' ')
1343 print(macro, end=' ')
1344
1344
1345 @magic_arguments.magic_arguments()
1345 @magic_arguments.magic_arguments()
1346 @magic_arguments.argument('output', type=str, default='', nargs='?',
1346 @magic_arguments.argument('output', type=str, default='', nargs='?',
1347 help="""The name of the variable in which to store output.
1347 help="""The name of the variable in which to store output.
1348 This is a utils.io.CapturedIO object with stdout/err attributes
1348 This is a utils.io.CapturedIO object with stdout/err attributes
1349 for the text of the captured output.
1349 for the text of the captured output.
1350
1350
1351 CapturedOutput also has a show() method for displaying the output,
1351 CapturedOutput also has a show() method for displaying the output,
1352 and __call__ as well, so you can use that to quickly display the
1352 and __call__ as well, so you can use that to quickly display the
1353 output.
1353 output.
1354
1354
1355 If unspecified, captured output is discarded.
1355 If unspecified, captured output is discarded.
1356 """
1356 """
1357 )
1357 )
1358 @magic_arguments.argument('--no-stderr', action="store_true",
1358 @magic_arguments.argument('--no-stderr', action="store_true",
1359 help="""Don't capture stderr."""
1359 help="""Don't capture stderr."""
1360 )
1360 )
1361 @magic_arguments.argument('--no-stdout', action="store_true",
1361 @magic_arguments.argument('--no-stdout', action="store_true",
1362 help="""Don't capture stdout."""
1362 help="""Don't capture stdout."""
1363 )
1363 )
1364 @magic_arguments.argument('--no-display', action="store_true",
1364 @magic_arguments.argument('--no-display', action="store_true",
1365 help="""Don't capture IPython's rich display."""
1365 help="""Don't capture IPython's rich display."""
1366 )
1366 )
1367 @cell_magic
1367 @cell_magic
1368 def capture(self, line, cell):
1368 def capture(self, line, cell):
1369 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1369 """run the cell, capturing stdout, stderr, and IPython's rich display() calls."""
1370 args = magic_arguments.parse_argstring(self.capture, line)
1370 args = magic_arguments.parse_argstring(self.capture, line)
1371 out = not args.no_stdout
1371 out = not args.no_stdout
1372 err = not args.no_stderr
1372 err = not args.no_stderr
1373 disp = not args.no_display
1373 disp = not args.no_display
1374 with capture_output(out, err, disp) as io:
1374 with capture_output(out, err, disp) as io:
1375 self.shell.run_cell(cell)
1375 self.shell.run_cell(cell)
1376 if args.output:
1376 if args.output:
1377 self.shell.user_ns[args.output] = io
1377 self.shell.user_ns[args.output] = io
1378
1378
1379 def parse_breakpoint(text, current_file):
1379 def parse_breakpoint(text, current_file):
1380 '''Returns (file, line) for file:line and (current_file, line) for line'''
1380 '''Returns (file, line) for file:line and (current_file, line) for line'''
1381 colon = text.find(':')
1381 colon = text.find(':')
1382 if colon == -1:
1382 if colon == -1:
1383 return current_file, int(text)
1383 return current_file, int(text)
1384 else:
1384 else:
1385 return text[:colon], int(text[colon+1:])
1385 return text[:colon], int(text[colon+1:])
1386
1386
1387 def _format_time(timespan, precision=3):
1387 def _format_time(timespan, precision=3):
1388 """Formats the timespan in a human readable form"""
1388 """Formats the timespan in a human readable form"""
1389
1389
1390 if timespan >= 60.0:
1390 if timespan >= 60.0:
1391 # we have more than a minute, format that in a human readable form
1391 # we have more than a minute, format that in a human readable form
1392 # Idea from http://snipplr.com/view/5713/
1392 # Idea from http://snipplr.com/view/5713/
1393 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1393 parts = [("d", 60*60*24),("h", 60*60),("min", 60), ("s", 1)]
1394 time = []
1394 time = []
1395 leftover = timespan
1395 leftover = timespan
1396 for suffix, length in parts:
1396 for suffix, length in parts:
1397 value = int(leftover / length)
1397 value = int(leftover / length)
1398 if value > 0:
1398 if value > 0:
1399 leftover = leftover % length
1399 leftover = leftover % length
1400 time.append(u'%s%s' % (str(value), suffix))
1400 time.append(u'%s%s' % (str(value), suffix))
1401 if leftover < 1:
1401 if leftover < 1:
1402 break
1402 break
1403 return " ".join(time)
1403 return " ".join(time)
1404
1404
1405
1405
1406 # Unfortunately the unicode 'micro' symbol can cause problems in
1406 # Unfortunately the unicode 'micro' symbol can cause problems in
1407 # certain terminals.
1407 # certain terminals.
1408 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1408 # See bug: https://bugs.launchpad.net/ipython/+bug/348466
1409 # Try to prevent crashes by being more secure than it needs to
1409 # Try to prevent crashes by being more secure than it needs to
1410 # E.g. eclipse is able to print a Β΅, but has no sys.stdout.encoding set.
1410 # E.g. eclipse is able to print a Β΅, but has no sys.stdout.encoding set.
1411 units = [u"s", u"ms",u'us',"ns"] # the save value
1411 units = [u"s", u"ms",u'us',"ns"] # the save value
1412 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1412 if hasattr(sys.stdout, 'encoding') and sys.stdout.encoding:
1413 try:
1413 try:
1414 u'\xb5'.encode(sys.stdout.encoding)
1414 u'\xb5'.encode(sys.stdout.encoding)
1415 units = [u"s", u"ms",u'\xb5s',"ns"]
1415 units = [u"s", u"ms",u'\xb5s',"ns"]
1416 except:
1416 except:
1417 pass
1417 pass
1418 scaling = [1, 1e3, 1e6, 1e9]
1418 scaling = [1, 1e3, 1e6, 1e9]
1419
1419
1420 if timespan > 0.0:
1420 if timespan > 0.0:
1421 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1421 order = min(-int(math.floor(math.log10(timespan)) // 3), 3)
1422 else:
1422 else:
1423 order = 3
1423 order = 3
1424 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
1424 return u"%.*g %s" % (precision, timespan * scaling[order], units[order])
@@ -1,256 +1,256 b''
1 """
1 """
2 Module to define and register Terminal IPython shortcuts with
2 Module to define and register Terminal IPython shortcuts with
3 :mod:`prompt_toolkit`
3 :mod:`prompt_toolkit`
4 """
4 """
5
5
6 # Copyright (c) IPython Development Team.
6 # Copyright (c) IPython Development Team.
7 # Distributed under the terms of the Modified BSD License.
7 # Distributed under the terms of the Modified BSD License.
8
8
9 import warnings
9 import warnings
10 import signal
10 import signal
11 import sys
11 import sys
12 from typing import Callable
12 from typing import Callable
13
13
14
14
15 from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER
15 from prompt_toolkit.enums import DEFAULT_BUFFER, SEARCH_BUFFER
16 from prompt_toolkit.filters import (HasFocus, HasSelection, Condition,
16 from prompt_toolkit.filters import (HasFocus, HasSelection, Condition,
17 ViInsertMode, EmacsInsertMode, HasCompletions)
17 ViInsertMode, EmacsInsertMode, HasCompletions)
18 from prompt_toolkit.filters.cli import ViMode, ViNavigationMode
18 from prompt_toolkit.filters.cli import ViMode, ViNavigationMode
19 from prompt_toolkit.keys import Keys
19 from prompt_toolkit.keys import Keys
20 from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline
20 from prompt_toolkit.key_binding.bindings.completion import display_completions_like_readline
21
21
22 from IPython.utils.decorators import undoc
22 from IPython.utils.decorators import undoc
23
23
24 @undoc
24 @undoc
25 @Condition
25 @Condition
26 def cursor_in_leading_ws(cli):
26 def cursor_in_leading_ws(cli):
27 before = cli.application.buffer.document.current_line_before_cursor
27 before = cli.application.buffer.document.current_line_before_cursor
28 return (not before) or before.isspace()
28 return (not before) or before.isspace()
29
29
30 def register_ipython_shortcuts(registry, shell):
30 def register_ipython_shortcuts(registry, shell):
31 """Set up the prompt_toolkit keyboard shortcuts for IPython"""
31 """Set up the prompt_toolkit keyboard shortcuts for IPython"""
32 insert_mode = ViInsertMode() | EmacsInsertMode()
32 insert_mode = ViInsertMode() | EmacsInsertMode()
33
33
34 if getattr(shell, 'handle_return', None):
34 if getattr(shell, 'handle_return', None):
35 return_handler = shell.handle_return(shell)
35 return_handler = shell.handle_return(shell)
36 else:
36 else:
37 return_handler = newline_or_execute_outer(shell)
37 return_handler = newline_or_execute_outer(shell)
38
38
39 # Ctrl+J == Enter, seemingly
39 # Ctrl+J == Enter, seemingly
40 registry.add_binding(Keys.ControlJ,
40 registry.add_binding(Keys.ControlJ,
41 filter=(HasFocus(DEFAULT_BUFFER)
41 filter=(HasFocus(DEFAULT_BUFFER)
42 & ~HasSelection()
42 & ~HasSelection()
43 & insert_mode
43 & insert_mode
44 ))(return_handler)
44 ))(return_handler)
45
45
46 registry.add_binding(Keys.ControlBackslash)(force_exit)
46 registry.add_binding(Keys.ControlBackslash)(force_exit)
47
47
48 registry.add_binding(Keys.ControlP,
48 registry.add_binding(Keys.ControlP,
49 filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)
49 filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)
50 ))(previous_history_or_previous_completion)
50 ))(previous_history_or_previous_completion)
51
51
52 registry.add_binding(Keys.ControlN,
52 registry.add_binding(Keys.ControlN,
53 filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)
53 filter=(ViInsertMode() & HasFocus(DEFAULT_BUFFER)
54 ))(next_history_or_next_completion)
54 ))(next_history_or_next_completion)
55
55
56 registry.add_binding(Keys.ControlG,
56 registry.add_binding(Keys.ControlG,
57 filter=(HasFocus(DEFAULT_BUFFER) & HasCompletions()
57 filter=(HasFocus(DEFAULT_BUFFER) & HasCompletions()
58 ))(dismiss_completion)
58 ))(dismiss_completion)
59
59
60 registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER)
60 registry.add_binding(Keys.ControlC, filter=HasFocus(DEFAULT_BUFFER)
61 )(reset_buffer)
61 )(reset_buffer)
62
62
63 registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER)
63 registry.add_binding(Keys.ControlC, filter=HasFocus(SEARCH_BUFFER)
64 )(reset_search_buffer)
64 )(reset_search_buffer)
65
65
66 supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP'))
66 supports_suspend = Condition(lambda cli: hasattr(signal, 'SIGTSTP'))
67 registry.add_binding(Keys.ControlZ, filter=supports_suspend
67 registry.add_binding(Keys.ControlZ, filter=supports_suspend
68 )(suspend_to_bg)
68 )(suspend_to_bg)
69
69
70 # Ctrl+I == Tab
70 # Ctrl+I == Tab
71 registry.add_binding(Keys.ControlI,
71 registry.add_binding(Keys.ControlI,
72 filter=(HasFocus(DEFAULT_BUFFER)
72 filter=(HasFocus(DEFAULT_BUFFER)
73 & ~HasSelection()
73 & ~HasSelection()
74 & insert_mode
74 & insert_mode
75 & cursor_in_leading_ws
75 & cursor_in_leading_ws
76 ))(indent_buffer)
76 ))(indent_buffer)
77
77
78 registry.add_binding(Keys.ControlO,
78 registry.add_binding(Keys.ControlO,
79 filter=(HasFocus(DEFAULT_BUFFER)
79 filter=(HasFocus(DEFAULT_BUFFER)
80 & EmacsInsertMode()))(newline_autoindent_outer(shell.input_splitter))
80 & EmacsInsertMode()))(newline_autoindent_outer(shell.input_transformer_manager))
81
81
82 registry.add_binding(Keys.F2,
82 registry.add_binding(Keys.F2,
83 filter=HasFocus(DEFAULT_BUFFER)
83 filter=HasFocus(DEFAULT_BUFFER)
84 )(open_input_in_editor)
84 )(open_input_in_editor)
85
85
86 if shell.display_completions == 'readlinelike':
86 if shell.display_completions == 'readlinelike':
87 registry.add_binding(Keys.ControlI,
87 registry.add_binding(Keys.ControlI,
88 filter=(HasFocus(DEFAULT_BUFFER)
88 filter=(HasFocus(DEFAULT_BUFFER)
89 & ~HasSelection()
89 & ~HasSelection()
90 & insert_mode
90 & insert_mode
91 & ~cursor_in_leading_ws
91 & ~cursor_in_leading_ws
92 ))(display_completions_like_readline)
92 ))(display_completions_like_readline)
93
93
94 if sys.platform == 'win32':
94 if sys.platform == 'win32':
95 registry.add_binding(Keys.ControlV,
95 registry.add_binding(Keys.ControlV,
96 filter=(
96 filter=(
97 HasFocus(
97 HasFocus(
98 DEFAULT_BUFFER) & ~ViMode()
98 DEFAULT_BUFFER) & ~ViMode()
99 ))(win_paste)
99 ))(win_paste)
100
100
101
101
102 def newline_or_execute_outer(shell):
102 def newline_or_execute_outer(shell):
103 def newline_or_execute(event):
103 def newline_or_execute(event):
104 """When the user presses return, insert a newline or execute the code."""
104 """When the user presses return, insert a newline or execute the code."""
105 b = event.current_buffer
105 b = event.current_buffer
106 d = b.document
106 d = b.document
107
107
108 if b.complete_state:
108 if b.complete_state:
109 cc = b.complete_state.current_completion
109 cc = b.complete_state.current_completion
110 if cc:
110 if cc:
111 b.apply_completion(cc)
111 b.apply_completion(cc)
112 else:
112 else:
113 b.cancel_completion()
113 b.cancel_completion()
114 return
114 return
115
115
116 # If there's only one line, treat it as if the cursor is at the end.
116 # If there's only one line, treat it as if the cursor is at the end.
117 # See https://github.com/ipython/ipython/issues/10425
117 # See https://github.com/ipython/ipython/issues/10425
118 if d.line_count == 1:
118 if d.line_count == 1:
119 check_text = d.text
119 check_text = d.text
120 else:
120 else:
121 check_text = d.text[:d.cursor_position]
121 check_text = d.text[:d.cursor_position]
122 status, indent = shell.input_splitter.check_complete(check_text + '\n')
122 status, indent = shell.input_transformer_manager.check_complete(check_text + '\n')
123
123
124 if not (d.on_last_line or
124 if not (d.on_last_line or
125 d.cursor_position_row >= d.line_count - d.empty_line_count_at_the_end()
125 d.cursor_position_row >= d.line_count - d.empty_line_count_at_the_end()
126 ):
126 ):
127 b.insert_text('\n' + (' ' * (indent or 0)))
127 b.insert_text('\n' + (' ' * (indent or 0)))
128 return
128 return
129
129
130 if (status != 'incomplete') and b.accept_action.is_returnable:
130 if (status != 'incomplete') and b.accept_action.is_returnable:
131 b.accept_action.validate_and_handle(event.cli, b)
131 b.accept_action.validate_and_handle(event.cli, b)
132 else:
132 else:
133 b.insert_text('\n' + (' ' * (indent or 0)))
133 b.insert_text('\n' + (' ' * (indent or 0)))
134 return newline_or_execute
134 return newline_or_execute
135
135
136
136
137 def previous_history_or_previous_completion(event):
137 def previous_history_or_previous_completion(event):
138 """
138 """
139 Control-P in vi edit mode on readline is history next, unlike default prompt toolkit.
139 Control-P in vi edit mode on readline is history next, unlike default prompt toolkit.
140
140
141 If completer is open this still select previous completion.
141 If completer is open this still select previous completion.
142 """
142 """
143 event.current_buffer.auto_up()
143 event.current_buffer.auto_up()
144
144
145
145
146 def next_history_or_next_completion(event):
146 def next_history_or_next_completion(event):
147 """
147 """
148 Control-N in vi edit mode on readline is history previous, unlike default prompt toolkit.
148 Control-N in vi edit mode on readline is history previous, unlike default prompt toolkit.
149
149
150 If completer is open this still select next completion.
150 If completer is open this still select next completion.
151 """
151 """
152 event.current_buffer.auto_down()
152 event.current_buffer.auto_down()
153
153
154
154
155 def dismiss_completion(event):
155 def dismiss_completion(event):
156 b = event.current_buffer
156 b = event.current_buffer
157 if b.complete_state:
157 if b.complete_state:
158 b.cancel_completion()
158 b.cancel_completion()
159
159
160
160
161 def reset_buffer(event):
161 def reset_buffer(event):
162 b = event.current_buffer
162 b = event.current_buffer
163 if b.complete_state:
163 if b.complete_state:
164 b.cancel_completion()
164 b.cancel_completion()
165 else:
165 else:
166 b.reset()
166 b.reset()
167
167
168
168
169 def reset_search_buffer(event):
169 def reset_search_buffer(event):
170 if event.current_buffer.document.text:
170 if event.current_buffer.document.text:
171 event.current_buffer.reset()
171 event.current_buffer.reset()
172 else:
172 else:
173 event.cli.push_focus(DEFAULT_BUFFER)
173 event.cli.push_focus(DEFAULT_BUFFER)
174
174
175 def suspend_to_bg(event):
175 def suspend_to_bg(event):
176 event.cli.suspend_to_background()
176 event.cli.suspend_to_background()
177
177
178 def force_exit(event):
178 def force_exit(event):
179 """
179 """
180 Force exit (with a non-zero return value)
180 Force exit (with a non-zero return value)
181 """
181 """
182 sys.exit("Quit")
182 sys.exit("Quit")
183
183
184 def indent_buffer(event):
184 def indent_buffer(event):
185 event.current_buffer.insert_text(' ' * 4)
185 event.current_buffer.insert_text(' ' * 4)
186
186
187 @undoc
187 @undoc
188 def newline_with_copy_margin(event):
188 def newline_with_copy_margin(event):
189 """
189 """
190 DEPRECATED since IPython 6.0
190 DEPRECATED since IPython 6.0
191
191
192 See :any:`newline_autoindent_outer` for a replacement.
192 See :any:`newline_autoindent_outer` for a replacement.
193
193
194 Preserve margin and cursor position when using
194 Preserve margin and cursor position when using
195 Control-O to insert a newline in EMACS mode
195 Control-O to insert a newline in EMACS mode
196 """
196 """
197 warnings.warn("`newline_with_copy_margin(event)` is deprecated since IPython 6.0. "
197 warnings.warn("`newline_with_copy_margin(event)` is deprecated since IPython 6.0. "
198 "see `newline_autoindent_outer(shell)(event)` for a replacement.",
198 "see `newline_autoindent_outer(shell)(event)` for a replacement.",
199 DeprecationWarning, stacklevel=2)
199 DeprecationWarning, stacklevel=2)
200
200
201 b = event.current_buffer
201 b = event.current_buffer
202 cursor_start_pos = b.document.cursor_position_col
202 cursor_start_pos = b.document.cursor_position_col
203 b.newline(copy_margin=True)
203 b.newline(copy_margin=True)
204 b.cursor_up(count=1)
204 b.cursor_up(count=1)
205 cursor_end_pos = b.document.cursor_position_col
205 cursor_end_pos = b.document.cursor_position_col
206 if cursor_start_pos != cursor_end_pos:
206 if cursor_start_pos != cursor_end_pos:
207 pos_diff = cursor_start_pos - cursor_end_pos
207 pos_diff = cursor_start_pos - cursor_end_pos
208 b.cursor_right(count=pos_diff)
208 b.cursor_right(count=pos_diff)
209
209
210 def newline_autoindent_outer(inputsplitter) -> Callable[..., None]:
210 def newline_autoindent_outer(inputsplitter) -> Callable[..., None]:
211 """
211 """
212 Return a function suitable for inserting a indented newline after the cursor.
212 Return a function suitable for inserting a indented newline after the cursor.
213
213
214 Fancier version of deprecated ``newline_with_copy_margin`` which should
214 Fancier version of deprecated ``newline_with_copy_margin`` which should
215 compute the correct indentation of the inserted line. That is to say, indent
215 compute the correct indentation of the inserted line. That is to say, indent
216 by 4 extra space after a function definition, class definition, context
216 by 4 extra space after a function definition, class definition, context
217 manager... And dedent by 4 space after ``pass``, ``return``, ``raise ...``.
217 manager... And dedent by 4 space after ``pass``, ``return``, ``raise ...``.
218 """
218 """
219
219
220 def newline_autoindent(event):
220 def newline_autoindent(event):
221 """insert a newline after the cursor indented appropriately."""
221 """insert a newline after the cursor indented appropriately."""
222 b = event.current_buffer
222 b = event.current_buffer
223 d = b.document
223 d = b.document
224
224
225 if b.complete_state:
225 if b.complete_state:
226 b.cancel_completion()
226 b.cancel_completion()
227 text = d.text[:d.cursor_position] + '\n'
227 text = d.text[:d.cursor_position] + '\n'
228 _, indent = inputsplitter.check_complete(text)
228 _, indent = inputsplitter.check_complete(text)
229 b.insert_text('\n' + (' ' * (indent or 0)), move_cursor=False)
229 b.insert_text('\n' + (' ' * (indent or 0)), move_cursor=False)
230
230
231 return newline_autoindent
231 return newline_autoindent
232
232
233
233
234 def open_input_in_editor(event):
234 def open_input_in_editor(event):
235 event.cli.current_buffer.tempfile_suffix = ".py"
235 event.cli.current_buffer.tempfile_suffix = ".py"
236 event.cli.current_buffer.open_in_editor(event.cli)
236 event.cli.current_buffer.open_in_editor(event.cli)
237
237
238
238
239 if sys.platform == 'win32':
239 if sys.platform == 'win32':
240 from IPython.core.error import TryNext
240 from IPython.core.error import TryNext
241 from IPython.lib.clipboard import (ClipboardEmpty,
241 from IPython.lib.clipboard import (ClipboardEmpty,
242 win32_clipboard_get,
242 win32_clipboard_get,
243 tkinter_clipboard_get)
243 tkinter_clipboard_get)
244
244
245 @undoc
245 @undoc
246 def win_paste(event):
246 def win_paste(event):
247 try:
247 try:
248 text = win32_clipboard_get()
248 text = win32_clipboard_get()
249 except TryNext:
249 except TryNext:
250 try:
250 try:
251 text = tkinter_clipboard_get()
251 text = tkinter_clipboard_get()
252 except (TryNext, ClipboardEmpty):
252 except (TryNext, ClipboardEmpty):
253 return
253 return
254 except ClipboardEmpty:
254 except ClipboardEmpty:
255 return
255 return
256 event.current_buffer.insert_text(text.replace('\t', ' ' * 4))
256 event.current_buffer.insert_text(text.replace('\t', ' ' * 4))
@@ -1,293 +1,293 b''
1 =======================
1 =======================
2 Specific config details
2 Specific config details
3 =======================
3 =======================
4
4
5 .. _custom_prompts:
5 .. _custom_prompts:
6
6
7 Custom Prompts
7 Custom Prompts
8 ==============
8 ==============
9
9
10 .. versionchanged:: 5.0
10 .. versionchanged:: 5.0
11
11
12 From IPython 5, prompts are produced as a list of Pygments tokens, which are
12 From IPython 5, prompts are produced as a list of Pygments tokens, which are
13 tuples of (token_type, text). You can customise prompts by writing a method
13 tuples of (token_type, text). You can customise prompts by writing a method
14 which generates a list of tokens.
14 which generates a list of tokens.
15
15
16 There are four kinds of prompt:
16 There are four kinds of prompt:
17
17
18 * The **in** prompt is shown before the first line of input
18 * The **in** prompt is shown before the first line of input
19 (default like ``In [1]:``).
19 (default like ``In [1]:``).
20 * The **continuation** prompt is shown before further lines of input
20 * The **continuation** prompt is shown before further lines of input
21 (default like ``...:``).
21 (default like ``...:``).
22 * The **rewrite** prompt is shown to highlight how special syntax has been
22 * The **rewrite** prompt is shown to highlight how special syntax has been
23 interpreted (default like ``----->``).
23 interpreted (default like ``----->``).
24 * The **out** prompt is shown before the result from evaluating the input
24 * The **out** prompt is shown before the result from evaluating the input
25 (default like ``Out[1]:``).
25 (default like ``Out[1]:``).
26
26
27 Custom prompts are supplied together as a class. If you want to customise only
27 Custom prompts are supplied together as a class. If you want to customise only
28 some of the prompts, inherit from :class:`IPython.terminal.prompts.Prompts`,
28 some of the prompts, inherit from :class:`IPython.terminal.prompts.Prompts`,
29 which defines the defaults. The required interface is like this:
29 which defines the defaults. The required interface is like this:
30
30
31 .. class:: MyPrompts(shell)
31 .. class:: MyPrompts(shell)
32
32
33 Prompt style definition. *shell* is a reference to the
33 Prompt style definition. *shell* is a reference to the
34 :class:`~.TerminalInteractiveShell` instance.
34 :class:`~.TerminalInteractiveShell` instance.
35
35
36 .. method:: in_prompt_tokens(cli=None)
36 .. method:: in_prompt_tokens(cli=None)
37 continuation_prompt_tokens(self, cli=None, width=None)
37 continuation_prompt_tokens(self, cli=None, width=None)
38 rewrite_prompt_tokens()
38 rewrite_prompt_tokens()
39 out_prompt_tokens()
39 out_prompt_tokens()
40
40
41 Return the respective prompts as lists of ``(token_type, text)`` tuples.
41 Return the respective prompts as lists of ``(token_type, text)`` tuples.
42
42
43 For continuation prompts, *width* is an integer representing the width of
43 For continuation prompts, *width* is an integer representing the width of
44 the prompt area in terminal columns.
44 the prompt area in terminal columns.
45
45
46 *cli*, where used, is the prompt_toolkit ``CommandLineInterface`` instance.
46 *cli*, where used, is the prompt_toolkit ``CommandLineInterface`` instance.
47 This is mainly for compatibility with the API prompt_toolkit expects.
47 This is mainly for compatibility with the API prompt_toolkit expects.
48
48
49 Here is an example Prompt class that will show the current working directory
49 Here is an example Prompt class that will show the current working directory
50 in the input prompt:
50 in the input prompt:
51
51
52 .. code-block:: python
52 .. code-block:: python
53
53
54 from IPython.terminal.prompts import Prompts, Token
54 from IPython.terminal.prompts import Prompts, Token
55 import os
55 import os
56
56
57 class MyPrompt(Prompts):
57 class MyPrompt(Prompts):
58 def in_prompt_tokens(self, cli=None):
58 def in_prompt_tokens(self, cli=None):
59 return [(Token, os.getcwd()),
59 return [(Token, os.getcwd()),
60 (Token.Prompt, ' >>>')]
60 (Token.Prompt, ' >>>')]
61
61
62 To set the new prompt, assign it to the ``prompts`` attribute of the IPython
62 To set the new prompt, assign it to the ``prompts`` attribute of the IPython
63 shell:
63 shell:
64
64
65 .. code-block:: python
65 .. code-block:: python
66
66
67 In [2]: ip = get_ipython()
67 In [2]: ip = get_ipython()
68 ...: ip.prompts = MyPrompt(ip)
68 ...: ip.prompts = MyPrompt(ip)
69
69
70 /home/bob >>> # it works
70 /home/bob >>> # it works
71
71
72 See ``IPython/example/utils/cwd_prompt.py`` for an example of how to write an
72 See ``IPython/example/utils/cwd_prompt.py`` for an example of how to write an
73 extensions to customise prompts.
73 extensions to customise prompts.
74
74
75 Inside IPython or in a startup script, you can use a custom prompts class
75 Inside IPython or in a startup script, you can use a custom prompts class
76 by setting ``get_ipython().prompts`` to an *instance* of the class.
76 by setting ``get_ipython().prompts`` to an *instance* of the class.
77 In configuration, ``TerminalInteractiveShell.prompts_class`` may be set to
77 In configuration, ``TerminalInteractiveShell.prompts_class`` may be set to
78 either the class object, or a string of its full importable name.
78 either the class object, or a string of its full importable name.
79
79
80 To include invisible terminal control sequences in a prompt, use
80 To include invisible terminal control sequences in a prompt, use
81 ``Token.ZeroWidthEscape`` as the token type. Tokens with this type are ignored
81 ``Token.ZeroWidthEscape`` as the token type. Tokens with this type are ignored
82 when calculating the width.
82 when calculating the width.
83
83
84 Colours in the prompt are determined by the token types and the highlighting
84 Colours in the prompt are determined by the token types and the highlighting
85 style; see below for more details. The tokens used in the default prompts are
85 style; see below for more details. The tokens used in the default prompts are
86 ``Prompt``, ``PromptNum``, ``OutPrompt`` and ``OutPromptNum``.
86 ``Prompt``, ``PromptNum``, ``OutPrompt`` and ``OutPromptNum``.
87
87
88 .. _termcolour:
88 .. _termcolour:
89
89
90 Terminal Colors
90 Terminal Colors
91 ===============
91 ===============
92
92
93 .. versionchanged:: 5.0
93 .. versionchanged:: 5.0
94
94
95 There are two main configuration options controlling colours.
95 There are two main configuration options controlling colours.
96
96
97 ``InteractiveShell.colors`` sets the colour of tracebacks and object info (the
97 ``InteractiveShell.colors`` sets the colour of tracebacks and object info (the
98 output from e.g. ``zip?``). It may also affect other things if the option below
98 output from e.g. ``zip?``). It may also affect other things if the option below
99 is set to ``'legacy'``. It has four case-insensitive values:
99 is set to ``'legacy'``. It has four case-insensitive values:
100 ``'nocolor', 'neutral', 'linux', 'lightbg'``. The default is *neutral*, which
100 ``'nocolor', 'neutral', 'linux', 'lightbg'``. The default is *neutral*, which
101 should be legible on either dark or light terminal backgrounds. *linux* is
101 should be legible on either dark or light terminal backgrounds. *linux* is
102 optimised for dark backgrounds and *lightbg* for light ones.
102 optimised for dark backgrounds and *lightbg* for light ones.
103
103
104 ``TerminalInteractiveShell.highlighting_style`` determines prompt colours and
104 ``TerminalInteractiveShell.highlighting_style`` determines prompt colours and
105 syntax highlighting. It takes the name (as a string) or class (as a subclass of
105 syntax highlighting. It takes the name (as a string) or class (as a subclass of
106 ``pygments.style.Style``) of a Pygments style, or the special value ``'legacy'``
106 ``pygments.style.Style``) of a Pygments style, or the special value ``'legacy'``
107 to pick a style in accordance with ``InteractiveShell.colors``.
107 to pick a style in accordance with ``InteractiveShell.colors``.
108
108
109 You can see the Pygments styles available on your system by running::
109 You can see the Pygments styles available on your system by running::
110
110
111 import pygments
111 import pygments
112 list(pygments.styles.get_all_styles())
112 list(pygments.styles.get_all_styles())
113
113
114 Additionally, ``TerminalInteractiveShell.highlighting_style_overrides`` can override
114 Additionally, ``TerminalInteractiveShell.highlighting_style_overrides`` can override
115 specific styles in the highlighting. It should be a dictionary mapping Pygments
115 specific styles in the highlighting. It should be a dictionary mapping Pygments
116 token types to strings defining the style. See `Pygments' documentation
116 token types to strings defining the style. See `Pygments' documentation
117 <http://pygments.org/docs/styles/#creating-own-styles>`__ for the language used
117 <http://pygments.org/docs/styles/#creating-own-styles>`__ for the language used
118 to define styles.
118 to define styles.
119
119
120 Colors in the pager
120 Colors in the pager
121 -------------------
121 -------------------
122
122
123 On some systems, the default pager has problems with ANSI colour codes.
123 On some systems, the default pager has problems with ANSI colour codes.
124 To configure your default pager to allow these:
124 To configure your default pager to allow these:
125
125
126 1. Set the environment PAGER variable to ``less``.
126 1. Set the environment PAGER variable to ``less``.
127 2. Set the environment LESS variable to ``-r`` (plus any other options
127 2. Set the environment LESS variable to ``-r`` (plus any other options
128 you always want to pass to less by default). This tells less to
128 you always want to pass to less by default). This tells less to
129 properly interpret control sequences, which is how color
129 properly interpret control sequences, which is how color
130 information is given to your terminal.
130 information is given to your terminal.
131
131
132 .. _editors:
132 .. _editors:
133
133
134 Editor configuration
134 Editor configuration
135 ====================
135 ====================
136
136
137 IPython can integrate with text editors in a number of different ways:
137 IPython can integrate with text editors in a number of different ways:
138
138
139 * Editors (such as `(X)Emacs`_, vim_ and TextMate_) can
139 * Editors (such as `(X)Emacs`_, vim_ and TextMate_) can
140 send code to IPython for execution.
140 send code to IPython for execution.
141
141
142 * IPython's ``%edit`` magic command can open an editor of choice to edit
142 * IPython's ``%edit`` magic command can open an editor of choice to edit
143 a code block.
143 a code block.
144
144
145 The %edit command (and its alias %ed) will invoke the editor set in your
145 The %edit command (and its alias %ed) will invoke the editor set in your
146 environment as :envvar:`EDITOR`. If this variable is not set, it will default
146 environment as :envvar:`EDITOR`. If this variable is not set, it will default
147 to vi under Linux/Unix and to notepad under Windows. You may want to set this
147 to vi under Linux/Unix and to notepad under Windows. You may want to set this
148 variable properly and to a lightweight editor which doesn't take too long to
148 variable properly and to a lightweight editor which doesn't take too long to
149 start (that is, something other than a new instance of Emacs). This way you
149 start (that is, something other than a new instance of Emacs). This way you
150 can edit multi-line code quickly and with the power of a real editor right
150 can edit multi-line code quickly and with the power of a real editor right
151 inside IPython.
151 inside IPython.
152
152
153 You can also control the editor by setting :attr:`TerminalInteractiveShell.editor`
153 You can also control the editor by setting :attr:`TerminalInteractiveShell.editor`
154 in :file:`ipython_config.py`.
154 in :file:`ipython_config.py`.
155
155
156 Vim
156 Vim
157 ---
157 ---
158
158
159 Paul Ivanov's `vim-ipython <https://github.com/ivanov/vim-ipython>`_ provides
159 Paul Ivanov's `vim-ipython <https://github.com/ivanov/vim-ipython>`_ provides
160 powerful IPython integration for vim.
160 powerful IPython integration for vim.
161
161
162 .. _emacs:
162 .. _emacs:
163
163
164 (X)Emacs
164 (X)Emacs
165 --------
165 --------
166
166
167 If you are a dedicated Emacs user, and want to use Emacs when IPython's
167 If you are a dedicated Emacs user, and want to use Emacs when IPython's
168 ``%edit`` magic command is called you should set up the Emacs server so that
168 ``%edit`` magic command is called you should set up the Emacs server so that
169 new requests are handled by the original process. This means that almost no
169 new requests are handled by the original process. This means that almost no
170 time is spent in handling the request (assuming an Emacs process is already
170 time is spent in handling the request (assuming an Emacs process is already
171 running). For this to work, you need to set your EDITOR environment variable
171 running). For this to work, you need to set your EDITOR environment variable
172 to 'emacsclient'. The code below, supplied by Francois Pinard, can then be
172 to 'emacsclient'. The code below, supplied by Francois Pinard, can then be
173 used in your :file:`.emacs` file to enable the server:
173 used in your :file:`.emacs` file to enable the server:
174
174
175 .. code-block:: common-lisp
175 .. code-block:: common-lisp
176
176
177 (defvar server-buffer-clients)
177 (defvar server-buffer-clients)
178 (when (and (fboundp 'server-start) (string-equal (getenv "TERM") 'xterm))
178 (when (and (fboundp 'server-start) (string-equal (getenv "TERM") 'xterm))
179 (server-start)
179 (server-start)
180 (defun fp-kill-server-with-buffer-routine ()
180 (defun fp-kill-server-with-buffer-routine ()
181 (and server-buffer-clients (server-done)))
181 (and server-buffer-clients (server-done)))
182 (add-hook 'kill-buffer-hook 'fp-kill-server-with-buffer-routine))
182 (add-hook 'kill-buffer-hook 'fp-kill-server-with-buffer-routine))
183
183
184 Thanks to the work of Alexander Schmolck and Prabhu Ramachandran,
184 Thanks to the work of Alexander Schmolck and Prabhu Ramachandran,
185 currently (X)Emacs and IPython get along very well in other ways.
185 currently (X)Emacs and IPython get along very well in other ways.
186
186
187 With (X)EMacs >= 24, You can enable IPython in python-mode with:
187 With (X)EMacs >= 24, You can enable IPython in python-mode with:
188
188
189 .. code-block:: common-lisp
189 .. code-block:: common-lisp
190
190
191 (require 'python)
191 (require 'python)
192 (setq python-shell-interpreter "ipython")
192 (setq python-shell-interpreter "ipython")
193
193
194 .. _`(X)Emacs`: http://www.gnu.org/software/emacs/
194 .. _`(X)Emacs`: http://www.gnu.org/software/emacs/
195 .. _TextMate: http://macromates.com/
195 .. _TextMate: http://macromates.com/
196 .. _vim: http://www.vim.org/
196 .. _vim: http://www.vim.org/
197
197
198 .. _custom_keyboard_shortcuts:
198 .. _custom_keyboard_shortcuts:
199
199
200 Keyboard Shortcuts
200 Keyboard Shortcuts
201 ==================
201 ==================
202
202
203 .. versionchanged:: 5.0
203 .. versionchanged:: 5.0
204
204
205 You can customise keyboard shortcuts for terminal IPython. Put code like this in
205 You can customise keyboard shortcuts for terminal IPython. Put code like this in
206 a :ref:`startup file <startup_files>`::
206 a :ref:`startup file <startup_files>`::
207
207
208 from IPython import get_ipython
208 from IPython import get_ipython
209 from prompt_toolkit.enums import DEFAULT_BUFFER
209 from prompt_toolkit.enums import DEFAULT_BUFFER
210 from prompt_toolkit.keys import Keys
210 from prompt_toolkit.keys import Keys
211 from prompt_toolkit.filters import HasFocus, HasSelection, ViInsertMode, EmacsInsertMode
211 from prompt_toolkit.filters import HasFocus, HasSelection, ViInsertMode, EmacsInsertMode
212
212
213 ip = get_ipython()
213 ip = get_ipython()
214 insert_mode = ViInsertMode() | EmacsInsertMode()
214 insert_mode = ViInsertMode() | EmacsInsertMode()
215
215
216 def insert_unexpected(event):
216 def insert_unexpected(event):
217 buf = event.current_buffer
217 buf = event.current_buffer
218 buf.insert_text('The Spanish Inquisition')
218 buf.insert_text('The Spanish Inquisition')
219
219
220 # Register the shortcut if IPython is using prompt_toolkit
220 # Register the shortcut if IPython is using prompt_toolkit
221 if getattr(ip, 'pt_cli'):
221 if getattr(ip, 'pt_cli'):
222 registry = ip.pt_cli.application.key_bindings_registry
222 registry = ip.pt_cli.application.key_bindings_registry
223 registry.add_binding(Keys.ControlN,
223 registry.add_binding(Keys.ControlN,
224 filter=(HasFocus(DEFAULT_BUFFER)
224 filter=(HasFocus(DEFAULT_BUFFER)
225 & ~HasSelection()
225 & ~HasSelection()
226 & insert_mode))(insert_unexpected)
226 & insert_mode))(insert_unexpected)
227
227
228 For more information on filters and what you can do with the ``event`` object,
228 For more information on filters and what you can do with the ``event`` object,
229 `see the prompt_toolkit docs
229 `see the prompt_toolkit docs
230 <http://python-prompt-toolkit.readthedocs.io/en/latest/pages/building_prompts.html#adding-custom-key-bindings>`__.
230 <http://python-prompt-toolkit.readthedocs.io/en/latest/pages/building_prompts.html#adding-custom-key-bindings>`__.
231
231
232
232
233 Enter to execute
233 Enter to execute
234 ----------------
234 ----------------
235
235
236 In the Terminal IPython shell – which by default uses the ``prompt_toolkit``
236 In the Terminal IPython shell – which by default uses the ``prompt_toolkit``
237 interface, the semantic meaning of pressing the :kbd:`Enter` key can be
237 interface, the semantic meaning of pressing the :kbd:`Enter` key can be
238 ambiguous. In some case :kbd:`Enter` should execute code, and in others it
238 ambiguous. In some case :kbd:`Enter` should execute code, and in others it
239 should add a new line. IPython uses heuristics to decide whether to execute or
239 should add a new line. IPython uses heuristics to decide whether to execute or
240 insert a new line at cursor position. For example, if we detect that the current
240 insert a new line at cursor position. For example, if we detect that the current
241 code is not valid Python, then the user is likely editing code and the right
241 code is not valid Python, then the user is likely editing code and the right
242 behavior is to likely to insert a new line. If the current code is a simple
242 behavior is to likely to insert a new line. If the current code is a simple
243 statement like `ord('*')`, then the right behavior is likely to execute. Though
243 statement like `ord('*')`, then the right behavior is likely to execute. Though
244 the exact desired semantics often varies from users to users.
244 the exact desired semantics often varies from users to users.
245
245
246 As the exact behavior of :kbd:`Enter` is ambiguous, it has been special cased
246 As the exact behavior of :kbd:`Enter` is ambiguous, it has been special cased
247 to allow users to completely configure the behavior they like. Hence you can
247 to allow users to completely configure the behavior they like. Hence you can
248 have enter always execute code. If you prefer fancier behavior, you need to get
248 have enter always execute code. If you prefer fancier behavior, you need to get
249 your hands dirty and read the ``prompt_toolkit`` and IPython documentation
249 your hands dirty and read the ``prompt_toolkit`` and IPython documentation
250 though. See :ghpull:`10500`, set the
250 though. See :ghpull:`10500`, set the
251 ``c.TerminalInteractiveShell.handle_return`` option and get inspiration from the
251 ``c.TerminalInteractiveShell.handle_return`` option and get inspiration from the
252 following example that only auto-executes the input if it begins with a bang or
252 following example that only auto-executes the input if it begins with a bang or
253 a modulo character (``!`` or ``%``). To use the following code, add it to your
253 a modulo character (``!`` or ``%``). To use the following code, add it to your
254 IPython configuration::
254 IPython configuration::
255
255
256 def custom_return(shell):
256 def custom_return(shell):
257
257
258 """This function is required by the API. It takes a reference to
258 """This function is required by the API. It takes a reference to
259 the shell, which is the same thing `get_ipython()` evaluates to.
259 the shell, which is the same thing `get_ipython()` evaluates to.
260 This function must return a function that handles each keypress
260 This function must return a function that handles each keypress
261 event. That function, named `handle` here, references `shell`
261 event. That function, named `handle` here, references `shell`
262 by closure."""
262 by closure."""
263
263
264 def handle(event):
264 def handle(event):
265
265
266 """This function is called each time `Enter` is pressed,
266 """This function is called each time `Enter` is pressed,
267 and takes a reference to a Prompt Toolkit event object.
267 and takes a reference to a Prompt Toolkit event object.
268 If the current input starts with a bang or modulo, then
268 If the current input starts with a bang or modulo, then
269 the input is executed, otherwise a newline is entered,
269 the input is executed, otherwise a newline is entered,
270 followed by any spaces needed to auto-indent."""
270 followed by any spaces needed to auto-indent."""
271
271
272 # set up a few handy references to nested items...
272 # set up a few handy references to nested items...
273
273
274 buffer = event.current_buffer
274 buffer = event.current_buffer
275 document = buffer.document
275 document = buffer.document
276 text = document.text
276 text = document.text
277
277
278 if text.startswith('!') or text.startswith('%'): # execute the input...
278 if text.startswith('!') or text.startswith('%'): # execute the input...
279
279
280 buffer.accept_action.validate_and_handle(event.cli, buffer)
280 buffer.accept_action.validate_and_handle(event.cli, buffer)
281
281
282 else: # insert a newline with auto-indentation...
282 else: # insert a newline with auto-indentation...
283
283
284 if document.line_count > 1: text = text[:document.cursor_position]
284 if document.line_count > 1: text = text[:document.cursor_position]
285 indent = shell.input_splitter.check_complete(text + '\n')[1] or 0
285 indent = shell.input_transformer_manager.check_complete(text)[1] or 0
286 buffer.insert_text('\n' + ' ' * indent)
286 buffer.insert_text('\n' + ' ' * indent)
287
287
288 # if you just wanted a plain newline without any indentation, you
288 # if you just wanted a plain newline without any indentation, you
289 # could use `buffer.insert_text('\n')` instead of the lines above
289 # could use `buffer.insert_text('\n')` instead of the lines above
290
290
291 return handle
291 return handle
292
292
293 c.TerminalInteractiveShell.handle_return = custom_return
293 c.TerminalInteractiveShell.handle_return = custom_return
General Comments 0
You need to be logged in to leave comments. Login now