##// END OF EJS Templates
typos
Matthias Bussonnier -
Show More
@@ -1,638 +1,637 b''
1 """Input transformer machinery to support IPython special syntax.
1 """Input transformer machinery to support IPython special syntax.
2
2
3 This includes the machinery to recognise and transform ``%magic`` commands,
3 This includes the machinery to recognise and transform ``%magic`` commands,
4 ``!system`` commands, ``help?`` querying, prompt stripping, and so forth.
4 ``!system`` commands, ``help?`` querying, prompt stripping, and so forth.
5
5
6 Added: IPython 7.0. Replaces inputsplitter and inputtransformer which were
6 Added: IPython 7.0. Replaces inputsplitter and inputtransformer which were
7 deprecated in 7.0.
7 deprecated in 7.0.
8 """
8 """
9
9
10 # Copyright (c) IPython Development Team.
10 # Copyright (c) IPython Development Team.
11 # Distributed under the terms of the Modified BSD License.
11 # Distributed under the terms of the Modified BSD License.
12
12
13 from codeop import compile_command
13 from codeop import compile_command
14 import re
14 import re
15 import tokenize
15 import tokenize
16 from typing import List, Tuple
16 from typing import List, Tuple
17 import warnings
17 import warnings
18
18
19 _indent_re = re.compile(r'^[ \t]+')
19 _indent_re = re.compile(r'^[ \t]+')
20
20
21 def leading_indent(lines):
21 def leading_indent(lines):
22 """Remove leading indentation.
22 """Remove leading indentation.
23
23
24 If the first line starts with a spaces or tabs, the same whitespace will be
24 If the first line starts with a spaces or tabs, the same whitespace will be
25 removed from each following line in the cell.
25 removed from each following line in the cell.
26 """
26 """
27 m = _indent_re.match(lines[0])
27 m = _indent_re.match(lines[0])
28 if not m:
28 if not m:
29 return lines
29 return lines
30 space = m.group(0)
30 space = m.group(0)
31 n = len(space)
31 n = len(space)
32 return [l[n:] if l.startswith(space) else l
32 return [l[n:] if l.startswith(space) else l
33 for l in lines]
33 for l in lines]
34
34
35 class PromptStripper:
35 class PromptStripper:
36 """Remove matching input prompts from a block of input.
36 """Remove matching input prompts from a block of input.
37
37
38 Parameters
38 Parameters
39 ----------
39 ----------
40 prompt_re : regular expression
40 prompt_re : regular expression
41 A regular expression matching any input prompt (including continuation,
41 A regular expression matching any input prompt (including continuation,
42 e.g. ``...``)
42 e.g. ``...``)
43 initial_re : regular expression, optional
43 initial_re : regular expression, optional
44 A regular expression matching only the initial prompt, but not continuation.
44 A regular expression matching only the initial prompt, but not continuation.
45 If no initial expression is given, prompt_re will be used everywhere.
45 If no initial expression is given, prompt_re will be used everywhere.
46 Used mainly for plain Python prompts (``>>>``), where the continuation prompt
46 Used mainly for plain Python prompts (``>>>``), where the continuation prompt
47 ``...`` is a valid Python expression in Python 3, so shouldn't be stripped.
47 ``...`` is a valid Python expression in Python 3, so shouldn't be stripped.
48
48
49 If initial_re and prompt_re differ,
49 If initial_re and prompt_re differ,
50 only initial_re will be tested against the first line.
50 only initial_re will be tested against the first line.
51 If any prompt is found on the first two lines,
51 If any prompt is found on the first two lines,
52 prompts will be stripped from the rest of the block.
52 prompts will be stripped from the rest of the block.
53 """
53 """
54 def __init__(self, prompt_re, initial_re=None):
54 def __init__(self, prompt_re, initial_re=None):
55 self.prompt_re = prompt_re
55 self.prompt_re = prompt_re
56 self.initial_re = initial_re or prompt_re
56 self.initial_re = initial_re or prompt_re
57
57
58 def _strip(self, lines):
58 def _strip(self, lines):
59 return [self.prompt_re.sub('', l, count=1) for l in lines]
59 return [self.prompt_re.sub('', l, count=1) for l in lines]
60
60
61 def __call__(self, lines):
61 def __call__(self, lines):
62 if self.initial_re.match(lines[0]) or \
62 if self.initial_re.match(lines[0]) or \
63 (len(lines) > 1 and self.prompt_re.match(lines[1])):
63 (len(lines) > 1 and self.prompt_re.match(lines[1])):
64 return self._strip(lines)
64 return self._strip(lines)
65 return lines
65 return lines
66
66
67 classic_prompt = PromptStripper(
67 classic_prompt = PromptStripper(
68 prompt_re=re.compile(r'^(>>>|\.\.\.)( |$)'),
68 prompt_re=re.compile(r'^(>>>|\.\.\.)( |$)'),
69 initial_re=re.compile(r'^>>>( |$)')
69 initial_re=re.compile(r'^>>>( |$)')
70 )
70 )
71
71
72 ipython_prompt = PromptStripper(re.compile(r'^(In \[\d+\]: |\s*\.{3,}: ?)'))
72 ipython_prompt = PromptStripper(re.compile(r'^(In \[\d+\]: |\s*\.{3,}: ?)'))
73
73
74 def cell_magic(lines):
74 def cell_magic(lines):
75 if not lines[0].startswith('%%'):
75 if not lines[0].startswith('%%'):
76 return lines
76 return lines
77 if re.match('%%\w+\?', lines[0]):
77 if re.match('%%\w+\?', lines[0]):
78 # This case will be handled by help_end
78 # This case will be handled by help_end
79 return lines
79 return lines
80 magic_name, _, first_line = lines[0][2:-1].partition(' ')
80 magic_name, _, first_line = lines[0][2:-1].partition(' ')
81 body = ''.join(lines[1:])
81 body = ''.join(lines[1:])
82 return ['get_ipython().run_cell_magic(%r, %r, %r)\n'
82 return ['get_ipython().run_cell_magic(%r, %r, %r)\n'
83 % (magic_name, first_line, body)]
83 % (magic_name, first_line, body)]
84
84
85
85
86 def _find_assign_op(token_line):
86 def _find_assign_op(token_line):
87 """Get the index of the first assignment in the line ('=' not inside brackets)
87 """Get the index of the first assignment in the line ('=' not inside brackets)
88
88
89 Note: We don't try to support multiple special assignment (a = b = %foo)
89 Note: We don't try to support multiple special assignment (a = b = %foo)
90 """
90 """
91 paren_level = 0
91 paren_level = 0
92 for i, ti in enumerate(token_line):
92 for i, ti in enumerate(token_line):
93 s = ti.string
93 s = ti.string
94 if s == '=' and paren_level == 0:
94 if s == '=' and paren_level == 0:
95 return i
95 return i
96 if s in '([{':
96 if s in '([{':
97 paren_level += 1
97 paren_level += 1
98 elif s in ')]}':
98 elif s in ')]}':
99 if paren_level > 0:
99 if paren_level > 0:
100 paren_level -= 1
100 paren_level -= 1
101
101
102 def find_end_of_continued_line(lines, start_line: int):
102 def find_end_of_continued_line(lines, start_line: int):
103 """Find the last line of a line explicitly extended using backslashes.
103 """Find the last line of a line explicitly extended using backslashes.
104
104
105 Uses 0-indexed line numbers.
105 Uses 0-indexed line numbers.
106 """
106 """
107 end_line = start_line
107 end_line = start_line
108 while lines[end_line].endswith('\\\n'):
108 while lines[end_line].endswith('\\\n'):
109 end_line += 1
109 end_line += 1
110 if end_line >= len(lines):
110 if end_line >= len(lines):
111 break
111 break
112 return end_line
112 return end_line
113
113
114 def assemble_continued_line(lines, start: Tuple[int, int], end_line: int):
114 def assemble_continued_line(lines, start: Tuple[int, int], end_line: int):
115 """Assemble a single line from multiple continued line pieces
115 """Assemble a single line from multiple continued line pieces
116
116
117 Continued lines are lines ending in ``\``, and the line following the last
117 Continued lines are lines ending in ``\``, and the line following the last
118 ``\`` in the block.
118 ``\`` in the block.
119
119
120 For example, this code continues over multiple lines::
120 For example, this code continues over multiple lines::
121
121
122 if (assign_ix is not None) \
122 if (assign_ix is not None) \
123 and (len(line) >= assign_ix + 2) \
123 and (len(line) >= assign_ix + 2) \
124 and (line[assign_ix+1].string == '%') \
124 and (line[assign_ix+1].string == '%') \
125 and (line[assign_ix+2].type == tokenize.NAME):
125 and (line[assign_ix+2].type == tokenize.NAME):
126
126
127 This statement contains four continued line pieces.
127 This statement contains four continued line pieces.
128 Assembling these pieces into a single line would give::
128 Assembling these pieces into a single line would give::
129
129
130 if (assign_ix is not None) and (len(line) >= assign_ix + 2) and (line[...
130 if (assign_ix is not None) and (len(line) >= assign_ix + 2) and (line[...
131
131
132 This uses 0-indexed line numbers. *start* is (lineno, colno).
132 This uses 0-indexed line numbers. *start* is (lineno, colno).
133
133
134 Used to allow ``%magic`` and ``!system`` commands to be continued over
134 Used to allow ``%magic`` and ``!system`` commands to be continued over
135 multiple lines.
135 multiple lines.
136 """
136 """
137 parts = [lines[start[0]][start[1]:]] + lines[start[0]+1:end_line+1]
137 parts = [lines[start[0]][start[1]:]] + lines[start[0]+1:end_line+1]
138 return ' '.join([p[:-2] for p in parts[:-1]] # Strip backslash+newline
138 return ' '.join([p[:-2] for p in parts[:-1]] # Strip backslash+newline
139 + [parts[-1][:-1]]) # Strip newline from last line
139 + [parts[-1][:-1]]) # Strip newline from last line
140
140
141 class TokenTransformBase:
141 class TokenTransformBase:
142 """Base class for transformations which examine tokens.
142 """Base class for transformations which examine tokens.
143
143
144 Special syntax should not be transformed when it occurs inside strings or
144 Special syntax should not be transformed when it occurs inside strings or
145 comments. This is hard to reliably avoid with regexes. The solution is to
145 comments. This is hard to reliably avoid with regexes. The solution is to
146 tokenise the code as Python, and recognise the special syntax in the tokens.
146 tokenise the code as Python, and recognise the special syntax in the tokens.
147
147
148 IPython's special syntax is not valid Python syntax, so tokenising may go
148 IPython's special syntax is not valid Python syntax, so tokenising may go
149 wrong after the special syntax starts. These classes therefore find and
149 wrong after the special syntax starts. These classes therefore find and
150 transform *one* instance of special syntax at a time into regular Python
150 transform *one* instance of special syntax at a time into regular Python
151 syntax. After each transformation, tokens are regenerated to find the next
151 syntax. After each transformation, tokens are regenerated to find the next
152 piece of special syntax.
152 piece of special syntax.
153
153
154 Subclasses need to implement one class method (find)
154 Subclasses need to implement one class method (find)
155 and one regular method (transform).
155 and one regular method (transform).
156
156
157 The priority attribute can select which transformation to apply if multiple
157 The priority attribute can select which transformation to apply if multiple
158 transformers match in the same place. Lower numbers have higher priority.
158 transformers match in the same place. Lower numbers have higher priority.
159 This allows "%magic?" to be turned into a help call rather than a magic call.
159 This allows "%magic?" to be turned into a help call rather than a magic call.
160 """
160 """
161 # Lower numbers -> higher priority (for matches in the same location)
161 # Lower numbers -> higher priority (for matches in the same location)
162 priority = 10
162 priority = 10
163
163
164 def sortby(self):
164 def sortby(self):
165 return self.start_line, self.start_col, self.priority
165 return self.start_line, self.start_col, self.priority
166
166
167 def __init__(self, start):
167 def __init__(self, start):
168 self.start_line = start[0] - 1 # Shift from 1-index to 0-index
168 self.start_line = start[0] - 1 # Shift from 1-index to 0-index
169 self.start_col = start[1]
169 self.start_col = start[1]
170
170
171 @classmethod
171 @classmethod
172 def find(cls, tokens_by_line):
172 def find(cls, tokens_by_line):
173 """Find one instance of special syntax in the provided tokens.
173 """Find one instance of special syntax in the provided tokens.
174
174
175 Tokens are grouped into logical lines for convenience,
175 Tokens are grouped into logical lines for convenience,
176 so it is easy to e.g. look at the first token of each line.
176 so it is easy to e.g. look at the first token of each line.
177 *tokens_by_line* is a list of lists of tokenize.TokenInfo objects.
177 *tokens_by_line* is a list of lists of tokenize.TokenInfo objects.
178
178
179 This should return an instance of its class, pointing to the start
179 This should return an instance of its class, pointing to the start
180 position it has found, or None if it found no match.
180 position it has found, or None if it found no match.
181 """
181 """
182 raise NotImplementedError
182 raise NotImplementedError
183
183
184 def transform(self, lines: List[str]):
184 def transform(self, lines: List[str]):
185 """Transform one instance of special syntax found by ``find()``
185 """Transform one instance of special syntax found by ``find()``
186
186
187 Takes a list of strings representing physical lines,
187 Takes a list of strings representing physical lines,
188 returns a similar list of transformed lines.
188 returns a similar list of transformed lines.
189 """
189 """
190 raise NotImplementedError
190 raise NotImplementedError
191
191
192 class MagicAssign(TokenTransformBase):
192 class MagicAssign(TokenTransformBase):
193 """Transformer for assignments from magics (a = %foo)"""
193 """Transformer for assignments from magics (a = %foo)"""
194 @classmethod
194 @classmethod
195 def find(cls, tokens_by_line):
195 def find(cls, tokens_by_line):
196 """Find the first magic assignment (a = %foo) in the cell.
196 """Find the first magic assignment (a = %foo) in the cell.
197 """
197 """
198 for line in tokens_by_line:
198 for line in tokens_by_line:
199 assign_ix = _find_assign_op(line)
199 assign_ix = _find_assign_op(line)
200 if (assign_ix is not None) \
200 if (assign_ix is not None) \
201 and (len(line) >= assign_ix + 2) \
201 and (len(line) >= assign_ix + 2) \
202 and (line[assign_ix+1].string == '%') \
202 and (line[assign_ix+1].string == '%') \
203 and (line[assign_ix+2].type == tokenize.NAME):
203 and (line[assign_ix+2].type == tokenize.NAME):
204 return cls(line[assign_ix+1].start)
204 return cls(line[assign_ix+1].start)
205
205
206 def transform(self, lines: List[str]):
206 def transform(self, lines: List[str]):
207 """Transform a magic assignment found by the ``find()`` classmethod.
207 """Transform a magic assignment found by the ``find()`` classmethod.
208 """
208 """
209 start_line, start_col = self.start_line, self.start_col
209 start_line, start_col = self.start_line, self.start_col
210 lhs = lines[start_line][:start_col]
210 lhs = lines[start_line][:start_col]
211 end_line = find_end_of_continued_line(lines, start_line)
211 end_line = find_end_of_continued_line(lines, start_line)
212 rhs = assemble_continued_line(lines, (start_line, start_col), end_line)
212 rhs = assemble_continued_line(lines, (start_line, start_col), end_line)
213 assert rhs.startswith('%'), rhs
213 assert rhs.startswith('%'), rhs
214 magic_name, _, args = rhs[1:].partition(' ')
214 magic_name, _, args = rhs[1:].partition(' ')
215
215
216 lines_before = lines[:start_line]
216 lines_before = lines[:start_line]
217 call = "get_ipython().run_line_magic({!r}, {!r})".format(magic_name, args)
217 call = "get_ipython().run_line_magic({!r}, {!r})".format(magic_name, args)
218 new_line = lhs + call + '\n'
218 new_line = lhs + call + '\n'
219 lines_after = lines[end_line+1:]
219 lines_after = lines[end_line+1:]
220
220
221 return lines_before + [new_line] + lines_after
221 return lines_before + [new_line] + lines_after
222
222
223
223
224 class SystemAssign(TokenTransformBase):
224 class SystemAssign(TokenTransformBase):
225 """Transformer for assignments from system commands (a = !foo)"""
225 """Transformer for assignments from system commands (a = !foo)"""
226 @classmethod
226 @classmethod
227 def find(cls, tokens_by_line):
227 def find(cls, tokens_by_line):
228 """Find the first system assignment (a = !foo) in the cell.
228 """Find the first system assignment (a = !foo) in the cell.
229 """
229 """
230 for line in tokens_by_line:
230 for line in tokens_by_line:
231 assign_ix = _find_assign_op(line)
231 assign_ix = _find_assign_op(line)
232 if (assign_ix is not None) \
232 if (assign_ix is not None) \
233 and (len(line) >= assign_ix + 2) \
233 and (len(line) >= assign_ix + 2) \
234 and (line[assign_ix + 1].type == tokenize.ERRORTOKEN):
234 and (line[assign_ix + 1].type == tokenize.ERRORTOKEN):
235 ix = assign_ix + 1
235 ix = assign_ix + 1
236
236
237 while ix < len(line) and line[ix].type == tokenize.ERRORTOKEN:
237 while ix < len(line) and line[ix].type == tokenize.ERRORTOKEN:
238 if line[ix].string == '!':
238 if line[ix].string == '!':
239 return cls(line[ix].start)
239 return cls(line[ix].start)
240 elif not line[ix].string.isspace():
240 elif not line[ix].string.isspace():
241 break
241 break
242 ix += 1
242 ix += 1
243
243
244 def transform(self, lines: List[str]):
244 def transform(self, lines: List[str]):
245 """Transform a system assignment found by the ``find()`` classmethod.
245 """Transform a system assignment found by the ``find()`` classmethod.
246 """
246 """
247 start_line, start_col = self.start_line, self.start_col
247 start_line, start_col = self.start_line, self.start_col
248
248
249 lhs = lines[start_line][:start_col]
249 lhs = lines[start_line][:start_col]
250 end_line = find_end_of_continued_line(lines, start_line)
250 end_line = find_end_of_continued_line(lines, start_line)
251 rhs = assemble_continued_line(lines, (start_line, start_col), end_line)
251 rhs = assemble_continued_line(lines, (start_line, start_col), end_line)
252 assert rhs.startswith('!'), rhs
252 assert rhs.startswith('!'), rhs
253 cmd = rhs[1:]
253 cmd = rhs[1:]
254
254
255 lines_before = lines[:start_line]
255 lines_before = lines[:start_line]
256 call = "get_ipython().getoutput({!r})".format(cmd)
256 call = "get_ipython().getoutput({!r})".format(cmd)
257 new_line = lhs + call + '\n'
257 new_line = lhs + call + '\n'
258 lines_after = lines[end_line + 1:]
258 lines_after = lines[end_line + 1:]
259
259
260 return lines_before + [new_line] + lines_after
260 return lines_before + [new_line] + lines_after
261
261
262 # The escape sequences that define the syntax transformations IPython will
262 # The escape sequences that define the syntax transformations IPython will
263 # apply to user input. These can NOT be just changed here: many regular
263 # apply to user input. These can NOT be just changed here: many regular
264 # expressions and other parts of the code may use their hardcoded values, and
264 # expressions and other parts of the code may use their hardcoded values, and
265 # for all intents and purposes they constitute the 'IPython syntax', so they
265 # for all intents and purposes they constitute the 'IPython syntax', so they
266 # should be considered fixed.
266 # should be considered fixed.
267
267
268 ESC_SHELL = '!' # Send line to underlying system shell
268 ESC_SHELL = '!' # Send line to underlying system shell
269 ESC_SH_CAP = '!!' # Send line to system shell and capture output
269 ESC_SH_CAP = '!!' # Send line to system shell and capture output
270 ESC_HELP = '?' # Find information about object
270 ESC_HELP = '?' # Find information about object
271 ESC_HELP2 = '??' # Find extra-detailed information about object
271 ESC_HELP2 = '??' # Find extra-detailed information about object
272 ESC_MAGIC = '%' # Call magic function
272 ESC_MAGIC = '%' # Call magic function
273 ESC_MAGIC2 = '%%' # Call cell-magic function
273 ESC_MAGIC2 = '%%' # Call cell-magic function
274 ESC_QUOTE = ',' # Split args on whitespace, quote each as string and call
274 ESC_QUOTE = ',' # Split args on whitespace, quote each as string and call
275 ESC_QUOTE2 = ';' # Quote all args as a single string, call
275 ESC_QUOTE2 = ';' # Quote all args as a single string, call
276 ESC_PAREN = '/' # Call first argument with rest of line as arguments
276 ESC_PAREN = '/' # Call first argument with rest of line as arguments
277
277
278 ESCAPE_SINGLES = {'!', '?', '%', ',', ';', '/'}
278 ESCAPE_SINGLES = {'!', '?', '%', ',', ';', '/'}
279 ESCAPE_DOUBLES = {'!!', '??'} # %% (cell magic) is handled separately
279 ESCAPE_DOUBLES = {'!!', '??'} # %% (cell magic) is handled separately
280
280
281 def _make_help_call(target, esc, next_input=None):
281 def _make_help_call(target, esc, next_input=None):
282 """Prepares a pinfo(2)/psearch call from a target name and the escape
282 """Prepares a pinfo(2)/psearch call from a target name and the escape
283 (i.e. ? or ??)"""
283 (i.e. ? or ??)"""
284 method = 'pinfo2' if esc == '??' \
284 method = 'pinfo2' if esc == '??' \
285 else 'psearch' if '*' in target \
285 else 'psearch' if '*' in target \
286 else 'pinfo'
286 else 'pinfo'
287 arg = " ".join([method, target])
287 arg = " ".join([method, target])
288 #Prepare arguments for get_ipython().run_line_magic(magic_name, magic_args)
288 #Prepare arguments for get_ipython().run_line_magic(magic_name, magic_args)
289 t_magic_name, _, t_magic_arg_s = arg.partition(' ')
289 t_magic_name, _, t_magic_arg_s = arg.partition(' ')
290 t_magic_name = t_magic_name.lstrip(ESC_MAGIC)
290 t_magic_name = t_magic_name.lstrip(ESC_MAGIC)
291 if next_input is None:
291 if next_input is None:
292 return 'get_ipython().run_line_magic(%r, %r)' % (t_magic_name, t_magic_arg_s)
292 return 'get_ipython().run_line_magic(%r, %r)' % (t_magic_name, t_magic_arg_s)
293 else:
293 else:
294 return 'get_ipython().set_next_input(%r);get_ipython().run_line_magic(%r, %r)' % \
294 return 'get_ipython().set_next_input(%r);get_ipython().run_line_magic(%r, %r)' % \
295 (next_input, t_magic_name, t_magic_arg_s)
295 (next_input, t_magic_name, t_magic_arg_s)
296
296
297 def _tr_help(content):
297 def _tr_help(content):
298 """Translate lines escaped with: ?
298 """Translate lines escaped with: ?
299
299
300 A naked help line should fire the intro help screen (shell.show_usage())
300 A naked help line should fire the intro help screen (shell.show_usage())
301 """
301 """
302 if not content:
302 if not content:
303 return 'get_ipython().show_usage()'
303 return 'get_ipython().show_usage()'
304
304
305 return _make_help_call(content, '?')
305 return _make_help_call(content, '?')
306
306
307 def _tr_help2(content):
307 def _tr_help2(content):
308 """Translate lines escaped with: ??
308 """Translate lines escaped with: ??
309
309
310 A naked help line should fire the intro help screen (shell.show_usage())
310 A naked help line should fire the intro help screen (shell.show_usage())
311 """
311 """
312 if not content:
312 if not content:
313 return 'get_ipython().show_usage()'
313 return 'get_ipython().show_usage()'
314
314
315 return _make_help_call(content, '??')
315 return _make_help_call(content, '??')
316
316
317 def _tr_magic(content):
317 def _tr_magic(content):
318 "Translate lines escaped with a percent sign: %"
318 "Translate lines escaped with a percent sign: %"
319 name, _, args = content.partition(' ')
319 name, _, args = content.partition(' ')
320 return 'get_ipython().run_line_magic(%r, %r)' % (name, args)
320 return 'get_ipython().run_line_magic(%r, %r)' % (name, args)
321
321
322 def _tr_quote(content):
322 def _tr_quote(content):
323 "Translate lines escaped with a comma: ,"
323 "Translate lines escaped with a comma: ,"
324 name, _, args = content.partition(' ')
324 name, _, args = content.partition(' ')
325 return '%s("%s")' % (name, '", "'.join(args.split()) )
325 return '%s("%s")' % (name, '", "'.join(args.split()) )
326
326
327 def _tr_quote2(content):
327 def _tr_quote2(content):
328 "Translate lines escaped with a semicolon: ;"
328 "Translate lines escaped with a semicolon: ;"
329 name, _, args = content.partition(' ')
329 name, _, args = content.partition(' ')
330 return '%s("%s")' % (name, args)
330 return '%s("%s")' % (name, args)
331
331
332 def _tr_paren(content):
332 def _tr_paren(content):
333 "Translate lines escaped with a slash: /"
333 "Translate lines escaped with a slash: /"
334 name, _, args = content.partition(' ')
334 name, _, args = content.partition(' ')
335 return '%s(%s)' % (name, ", ".join(args.split()))
335 return '%s(%s)' % (name, ", ".join(args.split()))
336
336
337 tr = { ESC_SHELL : 'get_ipython().system({!r})'.format,
337 tr = { ESC_SHELL : 'get_ipython().system({!r})'.format,
338 ESC_SH_CAP : 'get_ipython().getoutput({!r})'.format,
338 ESC_SH_CAP : 'get_ipython().getoutput({!r})'.format,
339 ESC_HELP : _tr_help,
339 ESC_HELP : _tr_help,
340 ESC_HELP2 : _tr_help2,
340 ESC_HELP2 : _tr_help2,
341 ESC_MAGIC : _tr_magic,
341 ESC_MAGIC : _tr_magic,
342 ESC_QUOTE : _tr_quote,
342 ESC_QUOTE : _tr_quote,
343 ESC_QUOTE2 : _tr_quote2,
343 ESC_QUOTE2 : _tr_quote2,
344 ESC_PAREN : _tr_paren }
344 ESC_PAREN : _tr_paren }
345
345
346 class EscapedCommand(TokenTransformBase):
346 class EscapedCommand(TokenTransformBase):
347 """Transformer for escaped commands like %foo, !foo, or /foo"""
347 """Transformer for escaped commands like %foo, !foo, or /foo"""
348 @classmethod
348 @classmethod
349 def find(cls, tokens_by_line):
349 def find(cls, tokens_by_line):
350 """Find the first escaped command (%foo, !foo, etc.) in the cell.
350 """Find the first escaped command (%foo, !foo, etc.) in the cell.
351 """
351 """
352 for line in tokens_by_line:
352 for line in tokens_by_line:
353 ix = 0
353 ix = 0
354 while line[ix].type in {tokenize.INDENT, tokenize.DEDENT}:
354 while line[ix].type in {tokenize.INDENT, tokenize.DEDENT}:
355 ix += 1
355 ix += 1
356 if line[ix].string in ESCAPE_SINGLES:
356 if line[ix].string in ESCAPE_SINGLES:
357 return cls(line[ix].start)
357 return cls(line[ix].start)
358
358
359 def transform(self, lines):
359 def transform(self, lines):
360 """Transform an escaped line found by the ``find()`` classmethod.
360 """Transform an escaped line found by the ``find()`` classmethod.
361 """
361 """
362 start_line, start_col = self.start_line, self.start_col
362 start_line, start_col = self.start_line, self.start_col
363
363
364 indent = lines[start_line][:start_col]
364 indent = lines[start_line][:start_col]
365 end_line = find_end_of_continued_line(lines, start_line)
365 end_line = find_end_of_continued_line(lines, start_line)
366 line = assemble_continued_line(lines, (start_line, start_col), end_line)
366 line = assemble_continued_line(lines, (start_line, start_col), end_line)
367
367
368 if line[:2] in ESCAPE_DOUBLES:
368 if line[:2] in ESCAPE_DOUBLES:
369 escape, content = line[:2], line[2:]
369 escape, content = line[:2], line[2:]
370 else:
370 else:
371 escape, content = line[:1], line[1:]
371 escape, content = line[:1], line[1:]
372 call = tr[escape](content)
372 call = tr[escape](content)
373
373
374 lines_before = lines[:start_line]
374 lines_before = lines[:start_line]
375 new_line = indent + call + '\n'
375 new_line = indent + call + '\n'
376 lines_after = lines[end_line + 1:]
376 lines_after = lines[end_line + 1:]
377
377
378 return lines_before + [new_line] + lines_after
378 return lines_before + [new_line] + lines_after
379
379
380 _help_end_re = re.compile(r"""(%{0,2}
380 _help_end_re = re.compile(r"""(%{0,2}
381 [a-zA-Z_*][\w*]* # Variable name
381 [a-zA-Z_*][\w*]* # Variable name
382 (\.[a-zA-Z_*][\w*]*)* # .etc.etc
382 (\.[a-zA-Z_*][\w*]*)* # .etc.etc
383 )
383 )
384 (\?\??)$ # ? or ??
384 (\?\??)$ # ? or ??
385 """,
385 """,
386 re.VERBOSE)
386 re.VERBOSE)
387
387
388 class HelpEnd(TokenTransformBase):
388 class HelpEnd(TokenTransformBase):
389 """Transformer for help syntax: obj? and obj??"""
389 """Transformer for help syntax: obj? and obj??"""
390 # This needs to be higher priority (lower number) than EscapedCommand so
390 # This needs to be higher priority (lower number) than EscapedCommand so
391 # that inspecting magics (%foo?) works.
391 # that inspecting magics (%foo?) works.
392 priority = 5
392 priority = 5
393
393
394 def __init__(self, start, q_locn):
394 def __init__(self, start, q_locn):
395 super().__init__(start)
395 super().__init__(start)
396 self.q_line = q_locn[0] - 1 # Shift from 1-indexed to 0-indexed
396 self.q_line = q_locn[0] - 1 # Shift from 1-indexed to 0-indexed
397 self.q_col = q_locn[1]
397 self.q_col = q_locn[1]
398
398
399 @classmethod
399 @classmethod
400 def find(cls, tokens_by_line):
400 def find(cls, tokens_by_line):
401 """Find the first help command (foo?) in the cell.
401 """Find the first help command (foo?) in the cell.
402 """
402 """
403 for line in tokens_by_line:
403 for line in tokens_by_line:
404 # Last token is NEWLINE; look at last but one
404 # Last token is NEWLINE; look at last but one
405 if len(line) > 2 and line[-2].string == '?':
405 if len(line) > 2 and line[-2].string == '?':
406 # Find the first token that's not INDENT/DEDENT
406 # Find the first token that's not INDENT/DEDENT
407 ix = 0
407 ix = 0
408 while line[ix].type in {tokenize.INDENT, tokenize.DEDENT}:
408 while line[ix].type in {tokenize.INDENT, tokenize.DEDENT}:
409 ix += 1
409 ix += 1
410 return cls(line[ix].start, line[-2].start)
410 return cls(line[ix].start, line[-2].start)
411
411
412 def transform(self, lines):
412 def transform(self, lines):
413 """Transform a help command found by the ``find()`` classmethod.
413 """Transform a help command found by the ``find()`` classmethod.
414 """
414 """
415 piece = ''.join(lines[self.start_line:self.q_line+1])
415 piece = ''.join(lines[self.start_line:self.q_line+1])
416 indent, content = piece[:self.start_col], piece[self.start_col:]
416 indent, content = piece[:self.start_col], piece[self.start_col:]
417 lines_before = lines[:self.start_line]
417 lines_before = lines[:self.start_line]
418 lines_after = lines[self.q_line + 1:]
418 lines_after = lines[self.q_line + 1:]
419
419
420 m = _help_end_re.search(content)
420 m = _help_end_re.search(content)
421 assert m is not None, content
421 assert m is not None, content
422 target = m.group(1)
422 target = m.group(1)
423 esc = m.group(3)
423 esc = m.group(3)
424
424
425 # If we're mid-command, put it back on the next prompt for the user.
425 # If we're mid-command, put it back on the next prompt for the user.
426 next_input = None
426 next_input = None
427 if (not lines_before) and (not lines_after) \
427 if (not lines_before) and (not lines_after) \
428 and content.strip() != m.group(0):
428 and content.strip() != m.group(0):
429 next_input = content.rstrip('?\n')
429 next_input = content.rstrip('?\n')
430
430
431 call = _make_help_call(target, esc, next_input=next_input)
431 call = _make_help_call(target, esc, next_input=next_input)
432 new_line = indent + call + '\n'
432 new_line = indent + call + '\n'
433
433
434 return lines_before + [new_line] + lines_after
434 return lines_before + [new_line] + lines_after
435
435
436 def make_tokens_by_line(lines):
436 def make_tokens_by_line(lines):
437 """Tokenize a series of lines and group tokens by line.
437 """Tokenize a series of lines and group tokens by line.
438
438
439 The tokens for a multiline Python string or expression are
439 The tokens for a multiline Python string or expression are
440 grouped as one line.
440 grouped as one line.
441 """
441 """
442 # NL tokens are used inside multiline expressions, but also after blank
442 # NL tokens are used inside multiline expressions, but also after blank
443 # lines or comments. This is intentional - see https://bugs.python.org/issue17061
443 # lines or comments. This is intentional - see https://bugs.python.org/issue17061
444 # We want to group the former case together but split the latter, so we
444 # We want to group the former case together but split the latter, so we
445 # track parentheses level, similar to the internals of tokenize.
445 # track parentheses level, similar to the internals of tokenize.
446 NEWLINE, NL = tokenize.NEWLINE, tokenize.NL
446 NEWLINE, NL = tokenize.NEWLINE, tokenize.NL
447 tokens_by_line = [[]]
447 tokens_by_line = [[]]
448 parenlev = 0
448 parenlev = 0
449 try:
449 try:
450 for token in tokenize.generate_tokens(iter(lines).__next__):
450 for token in tokenize.generate_tokens(iter(lines).__next__):
451 tokens_by_line[-1].append(token)
451 tokens_by_line[-1].append(token)
452 if (token.type == NEWLINE) \
452 if (token.type == NEWLINE) \
453 or ((token.type == NL) and (parenlev <= 0)):
453 or ((token.type == NL) and (parenlev <= 0)):
454 tokens_by_line.append([])
454 tokens_by_line.append([])
455 elif token.string in {'(', '[', '{'}:
455 elif token.string in {'(', '[', '{'}:
456 parenlev += 1
456 parenlev += 1
457 elif token.string in {')', ']', '}'}:
457 elif token.string in {')', ']', '}'}:
458 if parenlev > 0:
458 if parenlev > 0:
459 parenlev -= 1
459 parenlev -= 1
460 except tokenize.TokenError:
460 except tokenize.TokenError:
461 # Input ended in a multiline string or expression. That's OK for us.
461 # Input ended in a multiline string or expression. That's OK for us.
462 pass
462 pass
463
463
464 return tokens_by_line
464 return tokens_by_line
465
465
466 def show_linewise_tokens(s: str):
466 def show_linewise_tokens(s: str):
467 """For investigation and debugging"""
467 """For investigation and debugging"""
468 if not s.endswith('\n'):
468 if not s.endswith('\n'):
469 s += '\n'
469 s += '\n'
470 lines = s.splitlines(keepends=True)
470 lines = s.splitlines(keepends=True)
471 for line in make_tokens_by_line(lines):
471 for line in make_tokens_by_line(lines):
472 print("Line -------")
472 print("Line -------")
473 for tokinfo in line:
473 for tokinfo in line:
474 print(" ", tokinfo)
474 print(" ", tokinfo)
475
475
476 # Arbitrary limit to prevent getting stuck in infinite loops
476 # Arbitrary limit to prevent getting stuck in infinite loops
477 TRANSFORM_LOOP_LIMIT = 500
477 TRANSFORM_LOOP_LIMIT = 500
478
478
479 class TransformerManager:
479 class TransformerManager:
480 """Applies various transformations to a cell or code block.
480 """Applies various transformations to a cell or code block.
481
481
482 The key methods for external use are ``transform_cell()``
482 The key methods for external use are ``transform_cell()``
483 and ``check_complete()``.
483 and ``check_complete()``.
484 """
484 """
485 def __init__(self):
485 def __init__(self):
486 self.cleanup_transforms = [
486 self.cleanup_transforms = [
487 leading_indent,
487 leading_indent,
488 classic_prompt,
488 classic_prompt,
489 ipython_prompt,
489 ipython_prompt,
490 ]
490 ]
491 self.line_transforms = [
491 self.line_transforms = [
492 cell_magic,
492 cell_magic,
493 ]
493 ]
494 self.token_transformers = [
494 self.token_transformers = [
495 MagicAssign,
495 MagicAssign,
496 SystemAssign,
496 SystemAssign,
497 EscapedCommand,
497 EscapedCommand,
498 HelpEnd,
498 HelpEnd,
499 ]
499 ]
500
500
501 def do_one_token_transform(self, lines):
501 def do_one_token_transform(self, lines):
502 """Find and run the transform earliest in the code.
502 """Find and run the transform earliest in the code.
503
503
504 Returns (changed, lines).
504 Returns (changed, lines).
505
505
506 This method is called repeatedly until changed is False, indicating
506 This method is called repeatedly until changed is False, indicating
507 that all available transformations are complete.
507 that all available transformations are complete.
508
508
509 The tokens following IPython special syntax might not be valid, so
509 The tokens following IPython special syntax might not be valid, so
510 the transformed code is retokenised every time to identify the next
510 the transformed code is retokenised every time to identify the next
511 piece of special syntax. Hopefully long code cells are mostly valid
511 piece of special syntax. Hopefully long code cells are mostly valid
512 Python, not using lots of IPython special syntax, so this shouldn't be
512 Python, not using lots of IPython special syntax, so this shouldn't be
513 a performance issue.
513 a performance issue.
514 """
514 """
515 tokens_by_line = make_tokens_by_line(lines)
515 tokens_by_line = make_tokens_by_line(lines)
516 candidates = []
516 candidates = []
517 for transformer_cls in self.token_transformers:
517 for transformer_cls in self.token_transformers:
518 transformer = transformer_cls.find(tokens_by_line)
518 transformer = transformer_cls.find(tokens_by_line)
519 if transformer:
519 if transformer:
520 candidates.append(transformer)
520 candidates.append(transformer)
521
521
522 if not candidates:
522 if not candidates:
523 # Nothing to transform
523 # Nothing to transform
524 return False, lines
524 return False, lines
525
525
526 transformer = min(candidates, key=TokenTransformBase.sortby)
526 transformer = min(candidates, key=TokenTransformBase.sortby)
527 return True, transformer.transform(lines)
527 return True, transformer.transform(lines)
528
528
529 def do_token_transforms(self, lines):
529 def do_token_transforms(self, lines):
530 for _ in range(TRANSFORM_LOOP_LIMIT):
530 for _ in range(TRANSFORM_LOOP_LIMIT):
531 changed, lines = self.do_one_token_transform(lines)
531 changed, lines = self.do_one_token_transform(lines)
532 if not changed:
532 if not changed:
533 return lines
533 return lines
534
534
535 raise RuntimeError("Input transformation still changing after "
535 raise RuntimeError("Input transformation still changing after "
536 "%d iterations. Aborting." % TRANSFORM_LOOP_LIMIT)
536 "%d iterations. Aborting." % TRANSFORM_LOOP_LIMIT)
537
537
538 def transform_cell(self, cell: str) -> str:
538 def transform_cell(self, cell: str) -> str:
539 """Transforms a cell of input code"""
539 """Transforms a cell of input code"""
540 if not cell.endswith('\n'):
540 if not cell.endswith('\n'):
541 cell += '\n' # Ensure the cell has a trailing newline
541 cell += '\n' # Ensure the cell has a trailing newline
542 lines = cell.splitlines(keepends=True)
542 lines = cell.splitlines(keepends=True)
543 for transform in self.cleanup_transforms + self.line_transforms:
543 for transform in self.cleanup_transforms + self.line_transforms:
544 #print(transform, lines)
545 lines = transform(lines)
544 lines = transform(lines)
546
545
547 lines = self.do_token_transforms(lines)
546 lines = self.do_token_transforms(lines)
548 return ''.join(lines)
547 return ''.join(lines)
549
548
550 def check_complete(self, cell: str):
549 def check_complete(self, cell: str):
551 """Return whether a block of code is ready to execute, or should be continued
550 """Return whether a block of code is ready to execute, or should be continued
552
551
553 Parameters
552 Parameters
554 ----------
553 ----------
555 source : string
554 source : string
556 Python input code, which can be multiline.
555 Python input code, which can be multiline.
557
556
558 Returns
557 Returns
559 -------
558 -------
560 status : str
559 status : str
561 One of 'complete', 'incomplete', or 'invalid' if source is not a
560 One of 'complete', 'incomplete', or 'invalid' if source is not a
562 prefix of valid code.
561 prefix of valid code.
563 indent_spaces : int or None
562 indent_spaces : int or None
564 The number of spaces by which to indent the next line of code. If
563 The number of spaces by which to indent the next line of code. If
565 status is not 'incomplete', this is None.
564 status is not 'incomplete', this is None.
566 """
565 """
567 if not cell.endswith('\n'):
566 if not cell.endswith('\n'):
568 cell += '\n' # Ensure the cell has a trailing newline
567 cell += '\n' # Ensure the cell has a trailing newline
569 lines = cell.splitlines(keepends=True)
568 lines = cell.splitlines(keepends=True)
570 if lines[-1][:-1].endswith('\\'):
569 if lines[-1][:-1].endswith('\\'):
571 # Explicit backslash continuation
570 # Explicit backslash continuation
572 return 'incomplete', find_last_indent(lines)
571 return 'incomplete', find_last_indent(lines)
573
572
574 try:
573 try:
575 for transform in self.cleanup_transforms:
574 for transform in self.cleanup_transforms:
576 lines = transform(lines)
575 lines = transform(lines)
577 except SyntaxError:
576 except SyntaxError:
578 return 'invalid', None
577 return 'invalid', None
579
578
580 if lines[0].startswith('%%'):
579 if lines[0].startswith('%%'):
581 # Special case for cell magics - completion marked by blank line
580 # Special case for cell magics - completion marked by blank line
582 if lines[-1].strip():
581 if lines[-1].strip():
583 return 'incomplete', find_last_indent(lines)
582 return 'incomplete', find_last_indent(lines)
584 else:
583 else:
585 return 'complete', None
584 return 'complete', None
586
585
587 try:
586 try:
588 for transform in self.line_transforms:
587 for transform in self.line_transforms:
589 lines = transform(lines)
588 lines = transform(lines)
590 lines = self.do_token_transforms(lines)
589 lines = self.do_token_transforms(lines)
591 except SyntaxError:
590 except SyntaxError:
592 return 'invalid', None
591 return 'invalid', None
593
592
594 tokens_by_line = make_tokens_by_line(lines)
593 tokens_by_line = make_tokens_by_line(lines)
595 if tokens_by_line[-1][-1].type != tokenize.ENDMARKER:
594 if tokens_by_line[-1][-1].type != tokenize.ENDMARKER:
596 # We're in a multiline string or expression
595 # We're in a multiline string or expression
597 return 'incomplete', find_last_indent(lines)
596 return 'incomplete', find_last_indent(lines)
598
597
599 # Find the last token on the previous line that's not NEWLINE or COMMENT
598 # Find the last token on the previous line that's not NEWLINE or COMMENT
600 toks_last_line = tokens_by_line[-2]
599 toks_last_line = tokens_by_line[-2]
601 ix = len(toks_last_line) - 1
600 ix = len(toks_last_line) - 1
602 while ix >= 0 and toks_last_line[ix].type in {tokenize.NEWLINE,
601 while ix >= 0 and toks_last_line[ix].type in {tokenize.NEWLINE,
603 tokenize.COMMENT}:
602 tokenize.COMMENT}:
604 ix -= 1
603 ix -= 1
605
604
606 if toks_last_line[ix].string == ':':
605 if toks_last_line[ix].string == ':':
607 # The last line starts a block (e.g. 'if foo:')
606 # The last line starts a block (e.g. 'if foo:')
608 ix = 0
607 ix = 0
609 while toks_last_line[ix].type in {tokenize.INDENT, tokenize.DEDENT}:
608 while toks_last_line[ix].type in {tokenize.INDENT, tokenize.DEDENT}:
610 ix += 1
609 ix += 1
611 indent = toks_last_line[ix].start[1]
610 indent = toks_last_line[ix].start[1]
612 return 'incomplete', indent + 4
611 return 'incomplete', indent + 4
613
612
614 # If there's a blank line at the end, assume we're ready to execute.
613 # If there's a blank line at the end, assume we're ready to execute.
615 if not lines[-1].strip():
614 if not lines[-1].strip():
616 return 'complete', None
615 return 'complete', None
617
616
618 # At this point, our checks think the code is complete (or invalid).
617 # At this point, our checks think the code is complete (or invalid).
619 # We'll use codeop.compile_command to check this with the real parser.
618 # We'll use codeop.compile_command to check this with the real parser.
620
619
621 try:
620 try:
622 with warnings.catch_warnings():
621 with warnings.catch_warnings():
623 warnings.simplefilter('error', SyntaxWarning)
622 warnings.simplefilter('error', SyntaxWarning)
624 res = compile_command(''.join(lines), symbol='exec')
623 res = compile_command(''.join(lines), symbol='exec')
625 except (SyntaxError, OverflowError, ValueError, TypeError,
624 except (SyntaxError, OverflowError, ValueError, TypeError,
626 MemoryError, SyntaxWarning):
625 MemoryError, SyntaxWarning):
627 return 'invalid', None
626 return 'invalid', None
628 else:
627 else:
629 if res is None:
628 if res is None:
630 return 'incomplete', find_last_indent(lines)
629 return 'incomplete', find_last_indent(lines)
631 return 'complete', None
630 return 'complete', None
632
631
633
632
634 def find_last_indent(lines):
633 def find_last_indent(lines):
635 m = _indent_re.match(lines[-1])
634 m = _indent_re.match(lines[-1])
636 if not m:
635 if not m:
637 return 0
636 return 0
638 return len(m.group(0).replace('\t', ' '*4))
637 return len(m.group(0).replace('\t', ' '*4))
@@ -1,222 +1,222 b''
1 .. _autoawait:
1 .. _autoawait:
2
2
3 Asynchronous in REPL: Autoawait
3 Asynchronous in REPL: Autoawait
4 ===============================
4 ===============================
5
5
6 .. note::
6 .. note::
7
7
8 This feature is experimental and behavior can change betwen python and
8 This feature is experimental and behavior can change between python and
9 IPython version without prior deprecation.
9 IPython version without prior deprecation.
10
10
11 Starting with IPython 7.0, and when user Python 3.6 and above, IPython offer the
11 Starting with IPython 7.0, and when user Python 3.6 and above, IPython offer the
12 ability to run asynchronous code from the REPL. Constructs which are
12 ability to run asynchronous code from the REPL. Constructs which are
13 :exc:`SyntaxError` s in the Python REPL can be used seamlessly in IPython.
13 :exc:`SyntaxError` s in the Python REPL can be used seamlessly in IPython.
14
14
15 The example given here are for terminal IPython, running async code in a
15 The example given here are for terminal IPython, running async code in a
16 notebook interface or any other frontend using the Jupyter protocol will need to
16 notebook interface or any other frontend using the Jupyter protocol will need to
17 use a newer version of IPykernel. The details of how async code runs in
17 use a newer version of IPykernel. The details of how async code runs in
18 IPykernel will differ between IPython, IPykernel and their versions.
18 IPykernel will differ between IPython, IPykernel and their versions.
19
19
20 When a supported library is used, IPython will automatically allow Futures and
20 When a supported library is used, IPython will automatically allow Futures and
21 Coroutines in the REPL to be ``await`` ed. This will happen if an :ref:`await
21 Coroutines in the REPL to be ``await`` ed. This will happen if an :ref:`await
22 <await>` (or any other async constructs like async-with, async-for) is use at
22 <await>` (or any other async constructs like async-with, async-for) is use at
23 top level scope, or if any structure valid only in `async def
23 top level scope, or if any structure valid only in `async def
24 <https://docs.python.org/3/reference/compound_stmts.html#async-def>`_ function
24 <https://docs.python.org/3/reference/compound_stmts.html#async-def>`_ function
25 context are present. For example, the following being a syntax error in the
25 context are present. For example, the following being a syntax error in the
26 Python REPL::
26 Python REPL::
27
27
28 Python 3.6.0
28 Python 3.6.0
29 [GCC 4.2.1]
29 [GCC 4.2.1]
30 Type "help", "copyright", "credits" or "license" for more information.
30 Type "help", "copyright", "credits" or "license" for more information.
31 >>> import aiohttp
31 >>> import aiohttp
32 >>> result = aiohttp.get('https://api.github.com')
32 >>> result = aiohttp.get('https://api.github.com')
33 >>> response = await result
33 >>> response = await result
34 File "<stdin>", line 1
34 File "<stdin>", line 1
35 response = await result
35 response = await result
36 ^
36 ^
37 SyntaxError: invalid syntax
37 SyntaxError: invalid syntax
38
38
39 Should behave as expected in the IPython REPL::
39 Should behave as expected in the IPython REPL::
40
40
41 Python 3.6.0
41 Python 3.6.0
42 Type 'copyright', 'credits' or 'license' for more information
42 Type 'copyright', 'credits' or 'license' for more information
43 IPython 7.0.0 -- An enhanced Interactive Python. Type '?' for help.
43 IPython 7.0.0 -- An enhanced Interactive Python. Type '?' for help.
44
44
45 In [1]: import aiohttp
45 In [1]: import aiohttp
46 ...: result = aiohttp.get('https://api.github.com')
46 ...: result = aiohttp.get('https://api.github.com')
47
47
48 In [2]: response = await result
48 In [2]: response = await result
49 <pause for a few 100s ms>
49 <pause for a few 100s ms>
50
50
51 In [3]: await response.json()
51 In [3]: await response.json()
52 Out[3]:
52 Out[3]:
53 {'authorizations_url': 'https://api.github.com/authorizations',
53 {'authorizations_url': 'https://api.github.com/authorizations',
54 'code_search_url': 'https://api.github.com/search/code?q={query}...',
54 'code_search_url': 'https://api.github.com/search/code?q={query}...',
55 ...
55 ...
56 }
56 }
57
57
58
58
59 You can use the ``c.InteractiveShell.autoawait`` configuration option and set it
59 You can use the ``c.InteractiveShell.autoawait`` configuration option and set it
60 to :any:`False` to deactivate automatic wrapping of asynchronous code. You can also
60 to :any:`False` to deactivate automatic wrapping of asynchronous code. You can also
61 use the :magic:`%autoawait` magic to toggle the behavior at runtime::
61 use the :magic:`%autoawait` magic to toggle the behavior at runtime::
62
62
63 In [1]: %autoawait False
63 In [1]: %autoawait False
64
64
65 In [2]: %autoawait
65 In [2]: %autoawait
66 IPython autoawait is `Off`, and set to use `asyncio`
66 IPython autoawait is `Off`, and set to use `asyncio`
67
67
68
68
69
69
70 By default IPython will assume integration with Python's provided
70 By default IPython will assume integration with Python's provided
71 :mod:`asyncio`, but integration with other libraries is provided. In particular
71 :mod:`asyncio`, but integration with other libraries is provided. In particular
72 we provide experimental integration with the ``curio`` and ``trio`` library.
72 we provide experimental integration with the ``curio`` and ``trio`` library.
73
73
74 You can switch current integration by using the
74 You can switch current integration by using the
75 ``c.InteractiveShell.loop_runner`` option or the ``autoawait <name
75 ``c.InteractiveShell.loop_runner`` option or the ``autoawait <name
76 integration>`` magic.
76 integration>`` magic.
77
77
78 For example::
78 For example::
79
79
80 In [1]: %autoawait trio
80 In [1]: %autoawait trio
81
81
82 In [2]: import trio
82 In [2]: import trio
83
83
84 In [3]: async def child(i):
84 In [3]: async def child(i):
85 ...: print(" child %s goes to sleep"%i)
85 ...: print(" child %s goes to sleep"%i)
86 ...: await trio.sleep(2)
86 ...: await trio.sleep(2)
87 ...: print(" child %s wakes up"%i)
87 ...: print(" child %s wakes up"%i)
88
88
89 In [4]: print('parent start')
89 In [4]: print('parent start')
90 ...: async with trio.open_nursery() as n:
90 ...: async with trio.open_nursery() as n:
91 ...: for i in range(5):
91 ...: for i in range(5):
92 ...: n.spawn(child, i)
92 ...: n.spawn(child, i)
93 ...: print('parent end')
93 ...: print('parent end')
94 parent start
94 parent start
95 child 2 goes to sleep
95 child 2 goes to sleep
96 child 0 goes to sleep
96 child 0 goes to sleep
97 child 3 goes to sleep
97 child 3 goes to sleep
98 child 1 goes to sleep
98 child 1 goes to sleep
99 child 4 goes to sleep
99 child 4 goes to sleep
100 <about 2 seconds pause>
100 <about 2 seconds pause>
101 child 2 wakes up
101 child 2 wakes up
102 child 1 wakes up
102 child 1 wakes up
103 child 0 wakes up
103 child 0 wakes up
104 child 3 wakes up
104 child 3 wakes up
105 child 4 wakes up
105 child 4 wakes up
106 parent end
106 parent end
107
107
108
108
109 In the above example, ``async with`` at top level scope is a syntax error in
109 In the above example, ``async with`` at top level scope is a syntax error in
110 Python.
110 Python.
111
111
112 Using this mode can have unexpected consequences if used in interaction with
112 Using this mode can have unexpected consequences if used in interaction with
113 other features of IPython and various registered extensions. In particular if you
113 other features of IPython and various registered extensions. In particular if you
114 are a direct or indirect user of the AST transformers, these may not apply to
114 are a direct or indirect user of the AST transformers, these may not apply to
115 your code.
115 your code.
116
116
117 When using command line IPython, the default loop (or runner) does not process
117 When using command line IPython, the default loop (or runner) does not process
118 in the background, so top level asynchronous code must finish for the REPL to
118 in the background, so top level asynchronous code must finish for the REPL to
119 allow you to enter more code. As with usual Python semantic, the awaitables are
119 allow you to enter more code. As with usual Python semantic, the awaitables are
120 started only when awaited for the first time. That is to say, in first example,
120 started only when awaited for the first time. That is to say, in first example,
121 no network request is done between ``In[1]`` and ``In[2]``.
121 no network request is done between ``In[1]`` and ``In[2]``.
122
122
123
123
124 Effects on IPython.embed()
124 Effects on IPython.embed()
125 ==========================
125 ==========================
126
126
127 IPython core being asynchronous, the use of ``IPython.embed()`` will now require
127 IPython core being asynchronous, the use of ``IPython.embed()`` will now require
128 a loop to run. By default IPython will use a fake coroutine runner which should
128 a loop to run. By default IPython will use a fake coroutine runner which should
129 allow ``IPython.embed()`` to be nested. Though this will prevent usage of the
129 allow ``IPython.embed()`` to be nested. Though this will prevent usage of the
130 ``autoawait`` feature when using IPython embed.
130 ``autoawait`` feature when using IPython embed.
131
131
132 You can set explicitly a coroutine runner for ``embed()`` if you desire to run
132 You can set explicitly a coroutine runner for ``embed()`` if you desire to run
133 asynchronous code, the exact behavior is though undefined.
133 asynchronous code, the exact behavior is though undefined.
134
134
135 Effects on Magics
135 Effects on Magics
136 =================
136 =================
137
137
138 A couple of magics (``%%timeit``, ``%timeit``, ``%%time``, ``%%prun``) have not
138 A couple of magics (``%%timeit``, ``%timeit``, ``%%time``, ``%%prun``) have not
139 yet been updated to work with asynchronous code and will raise syntax errors
139 yet been updated to work with asynchronous code and will raise syntax errors
140 when trying to use top-level ``await``. We welcome any contribution to help fix
140 when trying to use top-level ``await``. We welcome any contribution to help fix
141 those, and extra cases we haven't caught yet. We hope for better support in Cor
141 those, and extra cases we haven't caught yet. We hope for better support in Cor
142 Python for top-level Async code.
142 Python for top-level Async code.
143
143
144 Internals
144 Internals
145 =========
145 =========
146
146
147 As running asynchronous code is not supported in interactive REPL (as of Python
147 As running asynchronous code is not supported in interactive REPL (as of Python
148 3.7) we have to rely to a number of complex workaround and heuristic to allow
148 3.7) we have to rely to a number of complex workaround and heuristic to allow
149 this to happen. It is interesting to understand how this works in order to
149 this to happen. It is interesting to understand how this works in order to
150 comprehend potential bugs, or provide a custom runner.
150 comprehend potential bugs, or provide a custom runner.
151
151
152 Among the many approaches that are at our disposition, we find only one that
152 Among the many approaches that are at our disposition, we find only one that
153 suited out need. Under the hood we use the code object from a async-def function
153 suited out need. Under the hood we use the code object from a async-def function
154 and run it in global namespace after modifying it to not create a new
154 and run it in global namespace after modifying it to not create a new
155 ``locals()`` scope::
155 ``locals()`` scope::
156
156
157 async def inner_async():
157 async def inner_async():
158 locals().update(**global_namespace)
158 locals().update(**global_namespace)
159 #
159 #
160 # here is user code
160 # here is user code
161 #
161 #
162 return last_user_statement
162 return last_user_statement
163 codeobj = modify(inner_async.__code__)
163 codeobj = modify(inner_async.__code__)
164 coroutine = eval(codeobj, user_ns)
164 coroutine = eval(codeobj, user_ns)
165 display(loop_runner(coroutine))
165 display(loop_runner(coroutine))
166
166
167
167
168
168
169 The first thing you'll notice is that unlike classical ``exec``, there is only
169 The first thing you'll notice is that unlike classical ``exec``, there is only
170 one namespace. Second, user code runs in a function scope, and not a module
170 one namespace. Second, user code runs in a function scope, and not a module
171 scope.
171 scope.
172
172
173 On top of the above there are significant modification to the AST of
173 On top of the above there are significant modification to the AST of
174 ``function``, and ``loop_runner`` can be arbitrary complex. So there is a
174 ``function``, and ``loop_runner`` can be arbitrary complex. So there is a
175 significant overhead to this kind of code.
175 significant overhead to this kind of code.
176
176
177 By default the generated coroutine function will be consumed by Asyncio's
177 By default the generated coroutine function will be consumed by Asyncio's
178 ``loop_runner = asyncio.get_evenloop().run_until_complete()`` method if
178 ``loop_runner = asyncio.get_evenloop().run_until_complete()`` method if
179 ``async`` mode is deemed necessary, otherwise the coroutine will just be
179 ``async`` mode is deemed necessary, otherwise the coroutine will just be
180 exhausted in a simple runner. It is though possible to change the default
180 exhausted in a simple runner. It is though possible to change the default
181 runner.
181 runner.
182
182
183 A loop runner is a *synchronous* function responsible from running a coroutine
183 A loop runner is a *synchronous* function responsible from running a coroutine
184 object.
184 object.
185
185
186 The runner is responsible from ensuring that ``coroutine`` run to completion,
186 The runner is responsible from ensuring that ``coroutine`` run to completion,
187 and should return the result of executing the coroutine. Let's write a
187 and should return the result of executing the coroutine. Let's write a
188 runner for ``trio`` that print a message when used as an exercise, ``trio`` is
188 runner for ``trio`` that print a message when used as an exercise, ``trio`` is
189 special as it usually prefer to run a function object and make a coroutine by
189 special as it usually prefer to run a function object and make a coroutine by
190 itself, we can get around this limitation by wrapping it in an async-def without
190 itself, we can get around this limitation by wrapping it in an async-def without
191 parameters and passing this value to ``trio``::
191 parameters and passing this value to ``trio``::
192
192
193
193
194 In [1]: import trio
194 In [1]: import trio
195 ...: from types import CoroutineType
195 ...: from types import CoroutineType
196 ...:
196 ...:
197 ...: def trio_runner(coro:CoroutineType):
197 ...: def trio_runner(coro:CoroutineType):
198 ...: print('running asynchronous code')
198 ...: print('running asynchronous code')
199 ...: async def corowrap(coro):
199 ...: async def corowrap(coro):
200 ...: return await coro
200 ...: return await coro
201 ...: return trio.run(corowrap, coro)
201 ...: return trio.run(corowrap, coro)
202
202
203 We can set it up by passing it to ``%autoawait``::
203 We can set it up by passing it to ``%autoawait``::
204
204
205 In [2]: %autoawait trio_runner
205 In [2]: %autoawait trio_runner
206
206
207 In [3]: async def async_hello(name):
207 In [3]: async def async_hello(name):
208 ...: await trio.sleep(1)
208 ...: await trio.sleep(1)
209 ...: print(f'Hello {name} world !')
209 ...: print(f'Hello {name} world !')
210 ...: await trio.sleep(1)
210 ...: await trio.sleep(1)
211
211
212 In [4]: await async_hello('async')
212 In [4]: await async_hello('async')
213 running asynchronous code
213 running asynchronous code
214 Hello async world !
214 Hello async world !
215
215
216
216
217 Asynchronous programming in python (and in particular in the REPL) is still a
217 Asynchronous programming in python (and in particular in the REPL) is still a
218 relatively young subject. We expect some code to not behave as you expect, so
218 relatively young subject. We expect some code to not behave as you expect, so
219 feel free to contribute improvements to this codebase and give us feedback.
219 feel free to contribute improvements to this codebase and give us feedback.
220
220
221 We invite you to thoroughly test this feature and report any unexpected behavior
221 We invite you to thoroughly test this feature and report any unexpected behavior
222 as well as propose any improvement.
222 as well as propose any improvement.
@@ -1,68 +1,68 b''
1 .. Developers should add in this file, during each release cycle, information
1 .. Developers should add in this file, during each release cycle, information
2 .. about important changes they've made, in a summary format that's meant for
2 .. about important changes they've made, in a summary format that's meant for
3 .. end users. For each release we normally have three sections: features, bug
3 .. end users. For each release we normally have three sections: features, bug
4 .. fixes and api breakage.
4 .. fixes and api breakage.
5 .. Please remember to credit the authors of the contributions by name,
5 .. Please remember to credit the authors of the contributions by name,
6 .. especially when they are new users or developers who do not regularly
6 .. especially when they are new users or developers who do not regularly
7 .. participate in IPython's development.
7 .. participate in IPython's development.
8
8
9 .. _whatsnew_index:
9 .. _whatsnew_index:
10
10
11 =====================
11 =====================
12 What's new in IPython
12 What's new in IPython
13 =====================
13 =====================
14
14
15 ..
15 ..
16 this will appear in the docs if we are nto releasing a versin (ie is
16 this will appear in the docs if we are not releasing a versin (ie is
17 `_version_extra` in release.py is empty stringA
17 `_version_extra` in release.py is empty string
18
18
19 .. only:: ipydev
19 .. only:: ipydev
20
20
21 Developpement version in-progress features:
21 Development version in-progress features:
22
22
23 .. toctree::
23 .. toctree::
24
24
25 development
25 development
26
26
27 ..
27 ..
28 this make a hidden toctree that avoid sphinx to complain about documents
28 this make a hidden toctree that avoid sphinx to complain about documents
29 included nowhere when building docs for stable
29 included nowhere when building docs for stable
30
30
31 .. only:: ipystable
31 .. only:: ipystable
32
32
33 .. toctree::
33 .. toctree::
34 :hidden:
34 :hidden:
35
35
36 development
36 development
37
37
38 This section documents the changes that have been made in various versions of
38 This section documents the changes that have been made in various versions of
39 IPython. Users should consult these pages to learn about new features, bug
39 IPython. Users should consult these pages to learn about new features, bug
40 fixes and backwards incompatibilities. Developers should summarize the
40 fixes and backwards incompatibilities. Developers should summarize the
41 development work they do here in a user friendly format.
41 development work they do here in a user friendly format.
42
42
43 .. toctree::
43 .. toctree::
44 :maxdepth: 1
44 :maxdepth: 1
45
45
46 version7
46 version7
47 version6
47 version6
48 github-stats-6
48 github-stats-6
49 version5
49 version5
50 github-stats-5
50 github-stats-5
51 version4
51 version4
52 github-stats-4
52 github-stats-4
53 version3
53 version3
54 github-stats-3
54 github-stats-3
55 version3_widget_migration
55 version3_widget_migration
56 version2.0
56 version2.0
57 github-stats-2.0
57 github-stats-2.0
58 version1.0
58 version1.0
59 github-stats-1.0
59 github-stats-1.0
60 version0.13
60 version0.13
61 github-stats-0.13
61 github-stats-0.13
62 version0.12
62 version0.12
63 github-stats-0.12
63 github-stats-0.12
64 version0.11
64 version0.11
65 github-stats-0.11
65 github-stats-0.11
66 version0.10
66 version0.10
67 version0.9
67 version0.9
68 version0.8
68 version0.8
@@ -1,670 +1,670 b''
1 =============
1 =============
2 0.13 Series
2 0.13 Series
3 =============
3 =============
4
4
5 Release 0.13
5 Release 0.13
6 ============
6 ============
7
7
8 IPython 0.13 contains several major new features, as well as a large amount of
8 IPython 0.13 contains several major new features, as well as a large amount of
9 bug and regression fixes. The previous version (0.12) was released on December
9 bug and regression fixes. The previous version (0.12) was released on December
10 19 2011, and in this development cycle we had:
10 19 2011, and in this development cycle we had:
11
11
12 - ~6 months of work.
12 - ~6 months of work.
13 - 373 pull requests merged.
13 - 373 pull requests merged.
14 - 742 issues closed (non-pull requests).
14 - 742 issues closed (non-pull requests).
15 - contributions from 62 authors.
15 - contributions from 62 authors.
16 - 1760 commits.
16 - 1760 commits.
17 - a diff of 114226 lines.
17 - a diff of 114226 lines.
18
18
19 The amount of work included in this release is so large, that we can only cover
19 The amount of work included in this release is so large, that we can only cover
20 here the main highlights; please see our :ref:`detailed release statistics
20 here the main highlights; please see our :ref:`detailed release statistics
21 <issues_list_013>` for links to every issue and pull request closed on GitHub
21 <issues_list_013>` for links to every issue and pull request closed on GitHub
22 as well as a full list of individual contributors.
22 as well as a full list of individual contributors.
23
23
24
24
25 Major Notebook improvements: new user interface and more
25 Major Notebook improvements: new user interface and more
26 --------------------------------------------------------
26 --------------------------------------------------------
27
27
28 The IPython Notebook, which has proven since its release to be wildly popular,
28 The IPython Notebook, which has proven since its release to be wildly popular,
29 has seen a massive amount of work in this release cycle, leading to a
29 has seen a massive amount of work in this release cycle, leading to a
30 significantly improved user experience as well as many new features.
30 significantly improved user experience as well as many new features.
31
31
32 The first user-visible change is a reorganization of the user interface; the
32 The first user-visible change is a reorganization of the user interface; the
33 left panel has been removed and was replaced by a real menu system and a
33 left panel has been removed and was replaced by a real menu system and a
34 toolbar with icons. Both the toolbar and the header above the menu can be
34 toolbar with icons. Both the toolbar and the header above the menu can be
35 collapsed to leave an unobstructed working area:
35 collapsed to leave an unobstructed working area:
36
36
37 .. image:: ../_images/ipy_013_notebook_spectrogram.png
37 .. image:: ../_images/ipy_013_notebook_spectrogram.png
38 :width: 460px
38 :width: 460px
39 :alt: New user interface for Notebook
39 :alt: New user interface for Notebook
40 :align: center
40 :align: center
41 :target: ../_images/ipy_013_notebook_spectrogram.png
41 :target: ../_images/ipy_013_notebook_spectrogram.png
42
42
43 The notebook handles very long outputs much better than before (this was a
43 The notebook handles very long outputs much better than before (this was a
44 serious usability issue when running processes that generated massive amounts
44 serious usability issue when running processes that generated massive amounts
45 of output). Now, in the presence of outputs longer than ~100 lines, the
45 of output). Now, in the presence of outputs longer than ~100 lines, the
46 notebook will automatically collapse to a scrollable area and the entire left
46 notebook will automatically collapse to a scrollable area and the entire left
47 part of this area controls the display: one click in this area will expand the
47 part of this area controls the display: one click in this area will expand the
48 output region completely, and a double-click will hide it completely. This
48 output region completely, and a double-click will hide it completely. This
49 figure shows both the scrolled and hidden modes:
49 figure shows both the scrolled and hidden modes:
50
50
51 .. image:: ../_images/ipy_013_notebook_long_out.png
51 .. image:: ../_images/ipy_013_notebook_long_out.png
52 :width: 460px
52 :width: 460px
53 :alt: Scrolling and hiding of long output in the notebook.
53 :alt: Scrolling and hiding of long output in the notebook.
54 :align: center
54 :align: center
55 :target: ../_images/ipy_013_notebook_long_out.png
55 :target: ../_images/ipy_013_notebook_long_out.png
56
56
57 .. note::
57 .. note::
58
58
59 The auto-folding of long outputs is disabled in Firefox due to bugs in its
59 The auto-folding of long outputs is disabled in Firefox due to bugs in its
60 scrolling behavior. See :ghpull:`2047` for details.
60 scrolling behavior. See :ghpull:`2047` for details.
61
61
62 Uploading notebooks to the dashboard is now easier: in addition to drag and
62 Uploading notebooks to the dashboard is now easier: in addition to drag and
63 drop (which can be finicky sometimes), you can now click on the upload text and
63 drop (which can be finicky sometimes), you can now click on the upload text and
64 use a regular file dialog box to select notebooks to upload. Furthermore, the
64 use a regular file dialog box to select notebooks to upload. Furthermore, the
65 notebook dashboard now auto-refreshes its contents and offers buttons to shut
65 notebook dashboard now auto-refreshes its contents and offers buttons to shut
66 down any running kernels (:ghpull:`1739`):
66 down any running kernels (:ghpull:`1739`):
67
67
68 .. image:: ../_images/ipy_013_dashboard.png
68 .. image:: ../_images/ipy_013_dashboard.png
69 :width: 460px
69 :width: 460px
70 :alt: Improved dashboard
70 :alt: Improved dashboard
71 :align: center
71 :align: center
72 :target: ../_images/ipy_013_dashboard.png
72 :target: ../_images/ipy_013_dashboard.png
73
73
74
74
75 Cluster management
75 Cluster management
76 ~~~~~~~~~~~~~~~~~~
76 ~~~~~~~~~~~~~~~~~~
77
77
78 The notebook dashboard can now also start and stop clusters, thanks to a new
78 The notebook dashboard can now also start and stop clusters, thanks to a new
79 tab in the dashboard user interface:
79 tab in the dashboard user interface:
80
80
81 .. image:: ../_images/ipy_013_dashboard_cluster.png
81 .. image:: ../_images/ipy_013_dashboard_cluster.png
82 :width: 460px
82 :width: 460px
83 :alt: Cluster management from the notebook dashboard
83 :alt: Cluster management from the notebook dashboard
84 :align: center
84 :align: center
85 :target: ../_images/ipy_013_dashboard_cluster.png
85 :target: ../_images/ipy_013_dashboard_cluster.png
86
86
87 This interface allows, for each profile you have configured, to start and stop
87 This interface allows, for each profile you have configured, to start and stop
88 a cluster (and optionally override the default number of engines corresponding
88 a cluster (and optionally override the default number of engines corresponding
89 to that configuration). While this hides all error reporting, once you have a
89 to that configuration). While this hides all error reporting, once you have a
90 configuration that you know works smoothly, it is a very convenient interface
90 configuration that you know works smoothly, it is a very convenient interface
91 for controlling your parallel resources.
91 for controlling your parallel resources.
92
92
93
93
94 New notebook format
94 New notebook format
95 ~~~~~~~~~~~~~~~~~~~
95 ~~~~~~~~~~~~~~~~~~~
96
96
97 The notebooks saved now use version 3 of our format, which supports heading
97 The notebooks saved now use version 3 of our format, which supports heading
98 levels as well as the concept of 'raw' text cells that are not rendered as
98 levels as well as the concept of 'raw' text cells that are not rendered as
99 Markdown. These will be useful with converters_ we are developing, to pass raw
99 Markdown. These will be useful with converters_ we are developing, to pass raw
100 markup (say LaTeX). That conversion code is still under heavy development and
100 markup (say LaTeX). That conversion code is still under heavy development and
101 not quite ready for prime time, but we welcome help on this front so that we
101 not quite ready for prime time, but we welcome help on this front so that we
102 can merge it for full production use as soon as possible.
102 can merge it for full production use as soon as possible.
103
103
104 .. _converters: https://github.com/ipython/nbconvert
104 .. _converters: https://github.com/ipython/nbconvert
105
105
106 .. note::
106 .. note::
107
107
108 v3 notebooks can *not* be read by older versions of IPython, but we provide
108 v3 notebooks can *not* be read by older versions of IPython, but we provide
109 a `simple script`_ that you can use in case you need to export a v3
109 a `simple script`_ that you can use in case you need to export a v3
110 notebook to share with a v2 user.
110 notebook to share with a v2 user.
111
111
112 .. _simple script: https://gist.github.com/1935808
112 .. _simple script: https://gist.github.com/1935808
113
113
114
114
115 JavaScript refactoring
115 JavaScript refactoring
116 ~~~~~~~~~~~~~~~~~~~~~~
116 ~~~~~~~~~~~~~~~~~~~~~~
117
117
118 All the client-side JavaScript has been decoupled to ease reuse of parts of the
118 All the client-side JavaScript has been decoupled to ease reuse of parts of the
119 machinery without having to build a full-blown notebook. This will make it much
119 machinery without having to build a full-blown notebook. This will make it much
120 easier to communicate with an IPython kernel from existing web pages and to
120 easier to communicate with an IPython kernel from existing web pages and to
121 integrate single cells into other sites, without loading the full notebook
121 integrate single cells into other sites, without loading the full notebook
122 document-like UI. :ghpull:`1711`.
122 document-like UI. :ghpull:`1711`.
123
123
124 This refactoring also enables the possibility of writing dynamic javascript
124 This refactoring also enables the possibility of writing dynamic javascript
125 widgets that are returned from Python code and that present an interactive view
125 widgets that are returned from Python code and that present an interactive view
126 to the user, with callbacks in Javascript executing calls to the Kernel. This
126 to the user, with callbacks in Javascript executing calls to the Kernel. This
127 will enable many interactive elements to be added by users in notebooks.
127 will enable many interactive elements to be added by users in notebooks.
128
128
129 An example of this capability has been provided as a proof of concept in
129 An example of this capability has been provided as a proof of concept in
130 :file:`examples/widgets` that lets you directly communicate with one or more
130 :file:`examples/widgets` that lets you directly communicate with one or more
131 parallel engines, acting as a mini-console for parallel debugging and
131 parallel engines, acting as a mini-console for parallel debugging and
132 introspection.
132 introspection.
133
133
134
134
135 Improved tooltips
135 Improved tooltips
136 ~~~~~~~~~~~~~~~~~
136 ~~~~~~~~~~~~~~~~~
137
137
138 The object tooltips have gained some new functionality. By pressing tab several
138 The object tooltips have gained some new functionality. By pressing tab several
139 times, you can expand them to see more of a docstring, keep them visible as you
139 times, you can expand them to see more of a docstring, keep them visible as you
140 fill in a function's parameters, or transfer the information to the pager at the
140 fill in a function's parameters, or transfer the information to the pager at the
141 bottom of the screen. For the details, look at the example notebook
141 bottom of the screen. For the details, look at the example notebook
142 :file:`01_notebook_introduction.ipynb`.
142 :file:`01_notebook_introduction.ipynb`.
143
143
144 .. figure:: ../_images/ipy_013_notebook_tooltip.png
144 .. figure:: ../_images/ipy_013_notebook_tooltip.png
145 :width: 460px
145 :width: 460px
146 :alt: Improved tooltips in the notebook.
146 :alt: Improved tooltips in the notebook.
147 :align: center
147 :align: center
148 :target: ../_images/ipy_013_notebook_tooltip.png
148 :target: ../_images/ipy_013_notebook_tooltip.png
149
149
150 The new notebook tooltips.
150 The new notebook tooltips.
151
151
152 Other improvements to the Notebook
152 Other improvements to the Notebook
153 ----------------------------------
153 ----------------------------------
154
154
155 These are some other notable small improvements to the notebook, in addition to
155 These are some other notable small improvements to the notebook, in addition to
156 many bug fixes and minor changes to add polish and robustness throughout:
156 many bug fixes and minor changes to add polish and robustness throughout:
157
157
158 * The notebook pager (the area at the bottom) is now resizeable by dragging its
158 * The notebook pager (the area at the bottom) is now Resizable by dragging its
159 divider handle, a feature that had been requested many times by just about
159 divider handle, a feature that had been requested many times by just about
160 anyone who had used the notebook system. :ghpull:`1705`.
160 anyone who had used the notebook system. :ghpull:`1705`.
161
161
162 * It is now possible to open notebooks directly from the command line; for
162 * It is now possible to open notebooks directly from the command line; for
163 example: ``ipython notebook path/`` will automatically set ``path/`` as the
163 example: ``ipython notebook path/`` will automatically set ``path/`` as the
164 notebook directory, and ``ipython notebook path/foo.ipynb`` will further
164 notebook directory, and ``ipython notebook path/foo.ipynb`` will further
165 start with the ``foo.ipynb`` notebook opened. :ghpull:`1686`.
165 start with the ``foo.ipynb`` notebook opened. :ghpull:`1686`.
166
166
167 * If a notebook directory is specified with ``--notebook-dir`` (or with the
167 * If a notebook directory is specified with ``--notebook-dir`` (or with the
168 corresponding configuration flag ``NotebookManager.notebook_dir``), all
168 corresponding configuration flag ``NotebookManager.notebook_dir``), all
169 kernels start in this directory.
169 kernels start in this directory.
170
170
171 * Fix codemirror clearing of cells with ``Ctrl-Z``; :ghpull:`1965`.
171 * Fix codemirror clearing of cells with ``Ctrl-Z``; :ghpull:`1965`.
172
172
173 * Text (markdown) cells now line wrap correctly in the notebook, making them
173 * Text (markdown) cells now line wrap correctly in the notebook, making them
174 much easier to edit :ghpull:`1330`.
174 much easier to edit :ghpull:`1330`.
175
175
176 * PNG and JPEG figures returned from plots can be interactively resized in the
176 * PNG and JPEG figures returned from plots can be interactively resized in the
177 notebook, by dragging them from their lower left corner. :ghpull:`1832`.
177 notebook, by dragging them from their lower left corner. :ghpull:`1832`.
178
178
179 * Clear ``In []`` prompt numbers on "Clear All Output". For more
179 * Clear ``In []`` prompt numbers on "Clear All Output". For more
180 version-control-friendly ``.ipynb`` files, we now strip all prompt numbers
180 version-control-friendly ``.ipynb`` files, we now strip all prompt numbers
181 when doing a "Clear all output". This reduces the amount of noise in
181 when doing a "Clear all output". This reduces the amount of noise in
182 commit-to-commit diffs that would otherwise show the (highly variable) prompt
182 commit-to-commit diffs that would otherwise show the (highly variable) prompt
183 number changes. :ghpull:`1621`.
183 number changes. :ghpull:`1621`.
184
184
185 * The notebook server now requires *two* consecutive ``Ctrl-C`` within 5
185 * The notebook server now requires *two* consecutive ``Ctrl-C`` within 5
186 seconds (or an interactive confirmation) to terminate operation. This makes
186 seconds (or an interactive confirmation) to terminate operation. This makes
187 it less likely that you will accidentally kill a long-running server by
187 it less likely that you will accidentally kill a long-running server by
188 typing ``Ctrl-C`` in the wrong terminal. :ghpull:`1609`.
188 typing ``Ctrl-C`` in the wrong terminal. :ghpull:`1609`.
189
189
190 * Using ``Ctrl-S`` (or ``Cmd-S`` on a Mac) actually saves the notebook rather
190 * Using ``Ctrl-S`` (or ``Cmd-S`` on a Mac) actually saves the notebook rather
191 than providing the fairly useless browser html save dialog. :ghpull:`1334`.
191 than providing the fairly useless browser html save dialog. :ghpull:`1334`.
192
192
193 * Allow accessing local files from the notebook (in urls), by serving any local
193 * Allow accessing local files from the notebook (in urls), by serving any local
194 file as the url ``files/<relativepath>``. This makes it possible to, for
194 file as the url ``files/<relativepath>``. This makes it possible to, for
195 example, embed local images in a notebook. :ghpull:`1211`.
195 example, embed local images in a notebook. :ghpull:`1211`.
196
196
197
197
198 Cell magics
198 Cell magics
199 -----------
199 -----------
200
200
201 We have completely refactored the magic system, finally moving the magic
201 We have completely refactored the magic system, finally moving the magic
202 objects to standalone, independent objects instead of being the mixin class
202 objects to standalone, independent objects instead of being the mixin class
203 we'd had since the beginning of IPython (:ghpull:`1732`). Now, a separate base
203 we'd had since the beginning of IPython (:ghpull:`1732`). Now, a separate base
204 class is provided in :class:`IPython.core.magic.Magics` that users can subclass
204 class is provided in :class:`IPython.core.magic.Magics` that users can subclass
205 to create their own magics. Decorators are also provided to create magics from
205 to create their own magics. Decorators are also provided to create magics from
206 simple functions without the need for object orientation. Please see the
206 simple functions without the need for object orientation. Please see the
207 :ref:`magic` docs for further details.
207 :ref:`magic` docs for further details.
208
208
209 All builtin magics now exist in a few subclasses that group together related
209 All builtin magics now exist in a few subclasses that group together related
210 functionality, and the new :mod:`IPython.core.magics` package has been created
210 functionality, and the new :mod:`IPython.core.magics` package has been created
211 to organize this into smaller files.
211 to organize this into smaller files.
212
212
213 This cleanup was the last major piece of deep refactoring needed from the
213 This cleanup was the last major piece of deep refactoring needed from the
214 original 2001 codebase.
214 original 2001 codebase.
215
215
216 We have also introduced a new type of magic function, prefixed with `%%`
216 We have also introduced a new type of magic function, prefixed with `%%`
217 instead of `%`, which operates at the whole-cell level. A cell magic receives
217 instead of `%`, which operates at the whole-cell level. A cell magic receives
218 two arguments: the line it is called on (like a line magic) and the body of the
218 two arguments: the line it is called on (like a line magic) and the body of the
219 cell below it.
219 cell below it.
220
220
221 Cell magics are most natural in the notebook, but they also work in the
221 Cell magics are most natural in the notebook, but they also work in the
222 terminal and qt console, with the usual approach of using a blank line to
222 terminal and qt console, with the usual approach of using a blank line to
223 signal cell termination.
223 signal cell termination.
224
224
225 For example, to time the execution of several statements::
225 For example, to time the execution of several statements::
226
226
227 %%timeit x = 0 # setup
227 %%timeit x = 0 # setup
228 for i in range(100000):
228 for i in range(100000):
229 x += i**2
229 x += i**2
230
230
231 This is particularly useful to integrate code in another language, and cell
231 This is particularly useful to integrate code in another language, and cell
232 magics already exist for shell scripts, Cython, R and Octave. Using ``%%script
232 magics already exist for shell scripts, Cython, R and Octave. Using ``%%script
233 /usr/bin/foo``, you can run a cell in any interpreter that accepts code via
233 /usr/bin/foo``, you can run a cell in any interpreter that accepts code via
234 stdin.
234 stdin.
235
235
236 Another handy cell magic makes it easy to write short text files: ``%%file
236 Another handy cell magic makes it easy to write short text files: ``%%file
237 ~/save/to/here.txt``.
237 ~/save/to/here.txt``.
238
238
239 The following cell magics are now included by default; all those that use
239 The following cell magics are now included by default; all those that use
240 special interpreters (Perl, Ruby, bash, etc.) assume you have the requisite
240 special interpreters (Perl, Ruby, bash, etc.) assume you have the requisite
241 interpreter installed:
241 interpreter installed:
242
242
243 * ``%%!``: run cell body with the underlying OS shell; this is similar to
243 * ``%%!``: run cell body with the underlying OS shell; this is similar to
244 prefixing every line in the cell with ``!``.
244 prefixing every line in the cell with ``!``.
245
245
246 * ``%%bash``: run cell body under bash.
246 * ``%%bash``: run cell body under bash.
247
247
248 * ``%%capture``: capture the output of the code in the cell (and stderr as
248 * ``%%capture``: capture the output of the code in the cell (and stderr as
249 well). Useful to run codes that produce too much output that you don't even
249 well). Useful to run codes that produce too much output that you don't even
250 want scrolled.
250 want scrolled.
251
251
252 * ``%%file``: save cell body as a file.
252 * ``%%file``: save cell body as a file.
253
253
254 * ``%%perl``: run cell body using Perl.
254 * ``%%perl``: run cell body using Perl.
255
255
256 * ``%%prun``: run cell body with profiler (cell extension of ``%prun``).
256 * ``%%prun``: run cell body with profiler (cell extension of ``%prun``).
257
257
258 * ``%%python3``: run cell body using Python 3.
258 * ``%%python3``: run cell body using Python 3.
259
259
260 * ``%%ruby``: run cell body using Ruby.
260 * ``%%ruby``: run cell body using Ruby.
261
261
262 * ``%%script``: run cell body with the script specified in the first line.
262 * ``%%script``: run cell body with the script specified in the first line.
263
263
264 * ``%%sh``: run cell body using sh.
264 * ``%%sh``: run cell body using sh.
265
265
266 * ``%%sx``: run cell with system shell and capture process output (cell
266 * ``%%sx``: run cell with system shell and capture process output (cell
267 extension of ``%sx``).
267 extension of ``%sx``).
268
268
269 * ``%%system``: run cell with system shell (``%%!`` is an alias to this).
269 * ``%%system``: run cell with system shell (``%%!`` is an alias to this).
270
270
271 * ``%%timeit``: time the execution of the cell (extension of ``%timeit``).
271 * ``%%timeit``: time the execution of the cell (extension of ``%timeit``).
272
272
273 This is what some of the script-related magics look like in action:
273 This is what some of the script-related magics look like in action:
274
274
275 .. image:: ../_images/ipy_013_notebook_script_cells.png
275 .. image:: ../_images/ipy_013_notebook_script_cells.png
276 :width: 460px
276 :width: 460px
277 :alt: Cluster management from the notebook dashboard
277 :alt: Cluster management from the notebook dashboard
278 :align: center
278 :align: center
279 :target: ../_images/ipy_013_notebook_script_cells.png
279 :target: ../_images/ipy_013_notebook_script_cells.png
280
280
281 In addition, we have also a number of :ref:`extensions <extensions_overview>`
281 In addition, we have also a number of :ref:`extensions <extensions_overview>`
282 that provide specialized magics. These typically require additional software
282 that provide specialized magics. These typically require additional software
283 to run and must be manually loaded via ``%load_ext <extension name>``, but are
283 to run and must be manually loaded via ``%load_ext <extension name>``, but are
284 extremely useful. The following extensions are provided:
284 extremely useful. The following extensions are provided:
285
285
286 **Cython magics** (extension ``cythonmagic``)
286 **Cython magics** (extension ``cythonmagic``)
287 This extension provides magics to automatically build and compile Python
287 This extension provides magics to automatically build and compile Python
288 extension modules using the Cython_ language. You must install Cython
288 extension modules using the Cython_ language. You must install Cython
289 separately, as well as a C compiler, for this to work. The examples
289 separately, as well as a C compiler, for this to work. The examples
290 directory in the source distribution ships with a full notebook
290 directory in the source distribution ships with a full notebook
291 demonstrating these capabilities:
291 demonstrating these capabilities:
292
292
293 .. image:: ../_images/ipy_013_notebook_cythonmagic.png
293 .. image:: ../_images/ipy_013_notebook_cythonmagic.png
294 :width: 460px
294 :width: 460px
295 :alt: Cython magic
295 :alt: Cython magic
296 :align: center
296 :align: center
297 :target: ../_images/ipy_013_notebook_cythonmagic.png
297 :target: ../_images/ipy_013_notebook_cythonmagic.png
298
298
299 .. _cython: http://cython.org
299 .. _cython: http://cython.org
300
300
301 **Octave magics** (extension ``octavemagic``)
301 **Octave magics** (extension ``octavemagic``)
302 This extension provides several magics that support calling code written in
302 This extension provides several magics that support calling code written in
303 the Octave_ language for numerical computing. You can execute single-lines
303 the Octave_ language for numerical computing. You can execute single-lines
304 or whole blocks of Octave code, capture both output and figures inline
304 or whole blocks of Octave code, capture both output and figures inline
305 (just like matplotlib plots), and have variables automatically converted
305 (just like matplotlib plots), and have variables automatically converted
306 between the two languages. To use this extension, you must have Octave
306 between the two languages. To use this extension, you must have Octave
307 installed as well as the oct2py_ package. The examples
307 installed as well as the oct2py_ package. The examples
308 directory in the source distribution ships with a full notebook
308 directory in the source distribution ships with a full notebook
309 demonstrating these capabilities:
309 demonstrating these capabilities:
310
310
311 .. image:: ../_images/ipy_013_notebook_octavemagic.png
311 .. image:: ../_images/ipy_013_notebook_octavemagic.png
312 :width: 460px
312 :width: 460px
313 :alt: Octave magic
313 :alt: Octave magic
314 :align: center
314 :align: center
315 :target: ../_images/ipy_013_notebook_octavemagic.png
315 :target: ../_images/ipy_013_notebook_octavemagic.png
316
316
317 .. _octave: http://www.gnu.org/software/octave
317 .. _octave: http://www.gnu.org/software/octave
318 .. _oct2py: http://pypi.python.org/pypi/oct2py
318 .. _oct2py: http://pypi.python.org/pypi/oct2py
319
319
320 **R magics** (extension ``rmagic``)
320 **R magics** (extension ``rmagic``)
321 This extension provides several magics that support calling code written in
321 This extension provides several magics that support calling code written in
322 the R_ language for statistical data analysis. You can execute
322 the R_ language for statistical data analysis. You can execute
323 single-lines or whole blocks of R code, capture both output and figures
323 single-lines or whole blocks of R code, capture both output and figures
324 inline (just like matplotlib plots), and have variables automatically
324 inline (just like matplotlib plots), and have variables automatically
325 converted between the two languages. To use this extension, you must have
325 converted between the two languages. To use this extension, you must have
326 R installed as well as the rpy2_ package that bridges Python and R. The
326 R installed as well as the rpy2_ package that bridges Python and R. The
327 examples directory in the source distribution ships with a full notebook
327 examples directory in the source distribution ships with a full notebook
328 demonstrating these capabilities:
328 demonstrating these capabilities:
329
329
330 .. image:: ../_images/ipy_013_notebook_rmagic.png
330 .. image:: ../_images/ipy_013_notebook_rmagic.png
331 :width: 460px
331 :width: 460px
332 :alt: R magic
332 :alt: R magic
333 :align: center
333 :align: center
334 :target: ../_images/ipy_013_notebook_rmagic.png
334 :target: ../_images/ipy_013_notebook_rmagic.png
335
335
336 .. _R: http://www.r-project.org
336 .. _R: http://www.r-project.org
337 .. _rpy2: http://rpy.sourceforge.net/rpy2.html
337 .. _rpy2: http://rpy.sourceforge.net/rpy2.html
338
338
339
339
340 Tab completer improvements
340 Tab completer improvements
341 --------------------------
341 --------------------------
342
342
343 Useful tab-completion based on live inspection of objects is one of the most
343 Useful tab-completion based on live inspection of objects is one of the most
344 popular features of IPython. To make this process even more user-friendly, the
344 popular features of IPython. To make this process even more user-friendly, the
345 completers of both the Qt console and the Notebook have been reworked.
345 completers of both the Qt console and the Notebook have been reworked.
346
346
347 The Qt console comes with a new ncurses-like tab completer, activated by
347 The Qt console comes with a new ncurses-like tab completer, activated by
348 default, which lets you cycle through the available completions by pressing tab,
348 default, which lets you cycle through the available completions by pressing tab,
349 or select a completion with the arrow keys (:ghpull:`1851`).
349 or select a completion with the arrow keys (:ghpull:`1851`).
350
350
351 .. figure:: ../_images/ipy_013_qtconsole_completer.png
351 .. figure:: ../_images/ipy_013_qtconsole_completer.png
352 :width: 460px
352 :width: 460px
353 :alt: ncurses-like completer, with highlighted selection.
353 :alt: ncurses-like completer, with highlighted selection.
354 :align: center
354 :align: center
355 :target: ../_images/ipy_013_qtconsole_completer.png
355 :target: ../_images/ipy_013_qtconsole_completer.png
356
356
357 The new improved Qt console's ncurses-like completer allows to easily
357 The new improved Qt console's ncurses-like completer allows to easily
358 navigate thought long list of completions.
358 navigate thought long list of completions.
359
359
360 In the notebook, completions are now sourced both from object introspection and
360 In the notebook, completions are now sourced both from object introspection and
361 analysis of surrounding code, so limited completions can be offered for
361 analysis of surrounding code, so limited completions can be offered for
362 variables defined in the current cell, or while the kernel is busy
362 variables defined in the current cell, or while the kernel is busy
363 (:ghpull:`1711`).
363 (:ghpull:`1711`).
364
364
365
365
366 We have implemented a new configurable flag to control tab completion on
366 We have implemented a new configurable flag to control tab completion on
367 modules that provide the ``__all__`` attribute::
367 modules that provide the ``__all__`` attribute::
368
368
369 IPCompleter.limit_to__all__= Boolean
369 IPCompleter.limit_to__all__= Boolean
370
370
371 This instructs the completer to honor ``__all__`` for the completion.
371 This instructs the completer to honor ``__all__`` for the completion.
372 Specifically, when completing on ``object.<tab>``, if True: only those names
372 Specifically, when completing on ``object.<tab>``, if True: only those names
373 in ``obj.__all__`` will be included. When False [default]: the ``__all__``
373 in ``obj.__all__`` will be included. When False [default]: the ``__all__``
374 attribute is ignored. :ghpull:`1529`.
374 attribute is ignored. :ghpull:`1529`.
375
375
376
376
377 Improvements to the Qt console
377 Improvements to the Qt console
378 ------------------------------
378 ------------------------------
379
379
380 The Qt console continues to receive improvements and refinements, despite the
380 The Qt console continues to receive improvements and refinements, despite the
381 fact that it is by now a fairly mature and robust component. Lots of small
381 fact that it is by now a fairly mature and robust component. Lots of small
382 polish has gone into it, here are a few highlights:
382 polish has gone into it, here are a few highlights:
383
383
384 * A number of changes were made to the underlying code for easier integration
384 * A number of changes were made to the underlying code for easier integration
385 into other projects such as Spyder_ (:ghpull:`2007`, :ghpull:`2024`).
385 into other projects such as Spyder_ (:ghpull:`2007`, :ghpull:`2024`).
386
386
387 * Improved menus with a new Magic menu that is organized by magic groups (this
387 * Improved menus with a new Magic menu that is organized by magic groups (this
388 was made possible by the reorganization of the magic system
388 was made possible by the reorganization of the magic system
389 internals). :ghpull:`1782`.
389 internals). :ghpull:`1782`.
390
390
391 * Allow for restarting kernels without clearing the qtconsole, while leaving a
391 * Allow for restarting kernels without clearing the qtconsole, while leaving a
392 visible indication that the kernel has restarted. :ghpull:`1681`.
392 visible indication that the kernel has restarted. :ghpull:`1681`.
393
393
394 * Allow the native display of jpeg images in the qtconsole. :ghpull:`1643`.
394 * Allow the native display of jpeg images in the qtconsole. :ghpull:`1643`.
395
395
396 .. _spyder: https://code.google.com/p/spyderlib
396 .. _spyder: https://code.google.com/p/spyderlib
397
397
398
398
399
399
400 Parallel
400 Parallel
401 --------
401 --------
402
402
403 The parallel tools have been improved and fine-tuned on multiple fronts. Now,
403 The parallel tools have been improved and fine-tuned on multiple fronts. Now,
404 the creation of an :class:`IPython.parallel.Client` object automatically
404 the creation of an :class:`IPython.parallel.Client` object automatically
405 activates a line and cell magic function ``px`` that sends its code to all the
405 activates a line and cell magic function ``px`` that sends its code to all the
406 engines. Further magics can be easily created with the :meth:`.Client.activate`
406 engines. Further magics can be easily created with the :meth:`.Client.activate`
407 method, to conveniently execute code on any subset of engines. :ghpull:`1893`.
407 method, to conveniently execute code on any subset of engines. :ghpull:`1893`.
408
408
409 The ``%%px`` cell magic can also be given an optional targets argument, as well
409 The ``%%px`` cell magic can also be given an optional targets argument, as well
410 as a ``--out`` argument for storing its output.
410 as a ``--out`` argument for storing its output.
411
411
412 A new magic has also been added, ``%pxconfig``, that lets you configure various
412 A new magic has also been added, ``%pxconfig``, that lets you configure various
413 defaults of the parallel magics. As usual, type ``%pxconfig?`` for details.
413 defaults of the parallel magics. As usual, type ``%pxconfig?`` for details.
414
414
415 The exception reporting in parallel contexts has been improved to be easier to
415 The exception reporting in parallel contexts has been improved to be easier to
416 read. Now, IPython directly reports the remote exceptions without showing any
416 read. Now, IPython directly reports the remote exceptions without showing any
417 of the internal execution parts:
417 of the internal execution parts:
418
418
419 .. image:: ../_images/ipy_013_par_tb.png
419 .. image:: ../_images/ipy_013_par_tb.png
420 :width: 460px
420 :width: 460px
421 :alt: Improved parallel exceptions.
421 :alt: Improved parallel exceptions.
422 :align: center
422 :align: center
423 :target: ../_images/ipy_013_par_tb.png
423 :target: ../_images/ipy_013_par_tb.png
424
424
425 The parallel tools now default to using ``NoDB`` as the storage backend for
425 The parallel tools now default to using ``NoDB`` as the storage backend for
426 intermediate results. This means that the default usage case will have a
426 intermediate results. This means that the default usage case will have a
427 significantly reduced memory footprint, though certain advanced features are
427 significantly reduced memory footprint, though certain advanced features are
428 not available with this backend.
428 not available with this backend.
429
429
430 The parallel magics now display all output, so you can do parallel plotting or
430 The parallel magics now display all output, so you can do parallel plotting or
431 other actions with complex display. The ``px`` magic has now both line and cell
431 other actions with complex display. The ``px`` magic has now both line and cell
432 modes, and in cell mode finer control has been added about how to collate
432 modes, and in cell mode finer control has been added about how to collate
433 output from multiple engines. :ghpull:`1768`.
433 output from multiple engines. :ghpull:`1768`.
434
434
435 There have also been incremental improvements to the SSH launchers:
435 There have also been incremental improvements to the SSH launchers:
436
436
437 * add to_send/fetch steps for moving connection files around.
437 * add to_send/fetch steps for moving connection files around.
438
438
439 * add SSHProxyEngineSetLauncher, for invoking to `ipcluster engines` on a
439 * add SSHProxyEngineSetLauncher, for invoking to `ipcluster engines` on a
440 remote host. This can be used to start a set of engines via PBS/SGE/MPI
440 remote host. This can be used to start a set of engines via PBS/SGE/MPI
441 *remotely*.
441 *remotely*.
442
442
443 This makes the SSHLauncher usable on machines without shared filesystems.
443 This makes the SSHLauncher usable on machines without shared filesystems.
444
444
445 A number of 'sugar' methods/properties were added to AsyncResult that are
445 A number of 'sugar' methods/properties were added to AsyncResult that are
446 quite useful (:ghpull:`1548`) for everday work:
446 quite useful (:ghpull:`1548`) for everday work:
447
447
448 * ``ar.wall_time`` = received - submitted
448 * ``ar.wall_time`` = received - submitted
449 * ``ar.serial_time`` = sum of serial computation time
449 * ``ar.serial_time`` = sum of serial computation time
450 * ``ar.elapsed`` = time since submission (wall_time if done)
450 * ``ar.elapsed`` = time since submission (wall_time if done)
451 * ``ar.progress`` = (int) number of sub-tasks that have completed
451 * ``ar.progress`` = (int) number of sub-tasks that have completed
452 * ``len(ar)`` = # of tasks
452 * ``len(ar)`` = # of tasks
453 * ``ar.wait_interactive()``: prints progress
453 * ``ar.wait_interactive()``: prints progress
454
454
455 Added :meth:`.Client.spin_thread` / :meth:`~.Client.stop_spin_thread` for
455 Added :meth:`.Client.spin_thread` / :meth:`~.Client.stop_spin_thread` for
456 running spin in a background thread, to keep zmq queue clear. This can be used
456 running spin in a background thread, to keep zmq queue clear. This can be used
457 to ensure that timing information is as accurate as possible (at the cost of
457 to ensure that timing information is as accurate as possible (at the cost of
458 having a background thread active).
458 having a background thread active).
459
459
460 Set TaskScheduler.hwm default to 1 instead of 0. 1 has more
460 Set TaskScheduler.hwm default to 1 instead of 0. 1 has more
461 predictable/intuitive behavior, if often slower, and thus a more logical
461 predictable/intuitive behavior, if often slower, and thus a more logical
462 default. Users whose workloads require maximum throughput and are largely
462 default. Users whose workloads require maximum throughput and are largely
463 homogeneous in time per task can make the optimization themselves, but now the
463 homogeneous in time per task can make the optimization themselves, but now the
464 behavior will be less surprising to new users. :ghpull:`1294`.
464 behavior will be less surprising to new users. :ghpull:`1294`.
465
465
466
466
467 Kernel/Engine unification
467 Kernel/Engine unification
468 -------------------------
468 -------------------------
469
469
470 This is mostly work 'under the hood', but it is actually a *major* achievement
470 This is mostly work 'under the hood', but it is actually a *major* achievement
471 for the project that has deep implications in the long term: at last, we have
471 for the project that has deep implications in the long term: at last, we have
472 unified the main object that executes as the user's interactive shell (which we
472 unified the main object that executes as the user's interactive shell (which we
473 refer to as the *IPython kernel*) with the objects that run in all the worker
473 refer to as the *IPython kernel*) with the objects that run in all the worker
474 nodes of the parallel computing facilities (the *IPython engines*). Ever since
474 nodes of the parallel computing facilities (the *IPython engines*). Ever since
475 the first implementation of IPython's parallel code back in 2006, we had wanted
475 the first implementation of IPython's parallel code back in 2006, we had wanted
476 to have these two roles be played by the same machinery, but a number of
476 to have these two roles be played by the same machinery, but a number of
477 technical reasons had prevented that from being true.
477 technical reasons had prevented that from being true.
478
478
479 In this release we have now merged them, and this has a number of important
479 In this release we have now merged them, and this has a number of important
480 consequences:
480 consequences:
481
481
482 * It is now possible to connect any of our clients (qtconsole or terminal
482 * It is now possible to connect any of our clients (qtconsole or terminal
483 console) to any individual parallel engine, with the *exact* behavior of
483 console) to any individual parallel engine, with the *exact* behavior of
484 working at a 'regular' IPython console/qtconsole. This makes debugging,
484 working at a 'regular' IPython console/qtconsole. This makes debugging,
485 plotting, etc. in parallel scenarios vastly easier.
485 plotting, etc. in parallel scenarios vastly easier.
486
486
487 * Parallel engines can always execute arbitrary 'IPython code', that is, code
487 * Parallel engines can always execute arbitrary 'IPython code', that is, code
488 that has magics, shell extensions, etc. In combination with the ``%%px``
488 that has magics, shell extensions, etc. In combination with the ``%%px``
489 magics, it is thus extremely natural for example to send to all engines a
489 magics, it is thus extremely natural for example to send to all engines a
490 block of Cython or R code to be executed via the new Cython and R magics. For
490 block of Cython or R code to be executed via the new Cython and R magics. For
491 example, this snippet would send the R block to all active engines in a
491 example, this snippet would send the R block to all active engines in a
492 cluster::
492 cluster::
493
493
494 %%px
494 %%px
495 %%R
495 %%R
496 ... R code goes here
496 ... R code goes here
497
497
498 * It is possible to embed not only an interactive shell with the
498 * It is possible to embed not only an interactive shell with the
499 :func:`IPython.embed` call as always, but now you can also embed a *kernel*
499 :func:`IPython.embed` call as always, but now you can also embed a *kernel*
500 with :func:`IPython.embed_kernel()`. Embedding an IPython kernel in an
500 with :func:`IPython.embed_kernel()`. Embedding an IPython kernel in an
501 application is useful when you want to use :func:`IPython.embed` but don't
501 application is useful when you want to use :func:`IPython.embed` but don't
502 have a terminal attached on stdin and stdout.
502 have a terminal attached on stdin and stdout.
503
503
504 * The new :func:`IPython.parallel.bind_kernel` allows you to promote Engines to
504 * The new :func:`IPython.parallel.bind_kernel` allows you to promote Engines to
505 listening Kernels, and connect QtConsoles to an Engine and debug it
505 listening Kernels, and connect QtConsoles to an Engine and debug it
506 directly.
506 directly.
507
507
508 In addition, having a single core object through our entire architecture also
508 In addition, having a single core object through our entire architecture also
509 makes the project conceptually cleaner, easier to maintain and more robust.
509 makes the project conceptually cleaner, easier to maintain and more robust.
510 This took a lot of work to get in place, but we are thrilled to have this major
510 This took a lot of work to get in place, but we are thrilled to have this major
511 piece of architecture finally where we'd always wanted it to be.
511 piece of architecture finally where we'd always wanted it to be.
512
512
513
513
514 Official Public API
514 Official Public API
515 -------------------
515 -------------------
516
516
517 We have begun organizing our API for easier public use, with an eye towards an
517 We have begun organizing our API for easier public use, with an eye towards an
518 official IPython 1.0 release which will firmly maintain this API compatible for
518 official IPython 1.0 release which will firmly maintain this API compatible for
519 its entire lifecycle. There is now an :mod:`IPython.display` module that
519 its entire lifecycle. There is now an :mod:`IPython.display` module that
520 aggregates all display routines, and the :mod:`traitlets.config` namespace has
520 aggregates all display routines, and the :mod:`traitlets.config` namespace has
521 all public configuration tools. We will continue improving our public API
521 all public configuration tools. We will continue improving our public API
522 layout so that users only need to import names one level deeper than the main
522 layout so that users only need to import names one level deeper than the main
523 ``IPython`` package to access all public namespaces.
523 ``IPython`` package to access all public namespaces.
524
524
525
525
526 IPython notebook file icons
526 IPython notebook file icons
527 ---------------------------
527 ---------------------------
528
528
529 The directory ``docs/resources`` in the source distribution contains SVG and
529 The directory ``docs/resources`` in the source distribution contains SVG and
530 PNG versions of our file icons, as well as an ``Info.plist.example`` file with
530 PNG versions of our file icons, as well as an ``Info.plist.example`` file with
531 instructions to install them on Mac OSX. This is a first draft of our icons,
531 instructions to install them on Mac OSX. This is a first draft of our icons,
532 and we encourage contributions from users with graphic talent to improve them
532 and we encourage contributions from users with graphic talent to improve them
533 in the future.
533 in the future.
534
534
535
535
536 New top-level `locate` command
536 New top-level `locate` command
537 ------------------------------
537 ------------------------------
538
538
539 Add `locate` entry points; these would be useful for quickly locating IPython
539 Add `locate` entry points; these would be useful for quickly locating IPython
540 directories and profiles from other (non-Python) applications. :ghpull:`1762`.
540 directories and profiles from other (non-Python) applications. :ghpull:`1762`.
541
541
542 Examples::
542 Examples::
543
543
544 $> ipython locate
544 $> ipython locate
545 /Users/me/.ipython
545 /Users/me/.ipython
546
546
547 $> ipython locate profile foo
547 $> ipython locate profile foo
548 /Users/me/.ipython/profile_foo
548 /Users/me/.ipython/profile_foo
549
549
550 $> ipython locate profile
550 $> ipython locate profile
551 /Users/me/.ipython/profile_default
551 /Users/me/.ipython/profile_default
552
552
553 $> ipython locate profile dne
553 $> ipython locate profile dne
554 [ProfileLocate] Profile u'dne' not found.
554 [ProfileLocate] Profile u'dne' not found.
555
555
556
556
557 Other new features and improvements
557 Other new features and improvements
558 -----------------------------------
558 -----------------------------------
559
559
560 * **%install_ext**: A new magic function to install an IPython extension from
560 * **%install_ext**: A new magic function to install an IPython extension from
561 a URL. E.g. ``%install_ext
561 a URL. E.g. ``%install_ext
562 https://bitbucket.org/birkenfeld/ipython-physics/raw/default/physics.py``.
562 https://bitbucket.org/birkenfeld/ipython-physics/raw/default/physics.py``.
563
563
564 * The ``%loadpy`` magic is no longer restricted to Python files, and has been
564 * The ``%loadpy`` magic is no longer restricted to Python files, and has been
565 renamed ``%load``. The old name remains as an alias.
565 renamed ``%load``. The old name remains as an alias.
566
566
567 * New command line arguments will help external programs find IPython folders:
567 * New command line arguments will help external programs find IPython folders:
568 ``ipython locate`` finds the user's IPython directory, and ``ipython locate
568 ``ipython locate`` finds the user's IPython directory, and ``ipython locate
569 profile foo`` finds the folder for the 'foo' profile (if it exists).
569 profile foo`` finds the folder for the 'foo' profile (if it exists).
570
570
571 * The :envvar:`IPYTHON_DIR` environment variable, introduced in the Great
571 * The :envvar:`IPYTHON_DIR` environment variable, introduced in the Great
572 Reorganization of 0.11 and existing only in versions 0.11-0.13, has been
572 Reorganization of 0.11 and existing only in versions 0.11-0.13, has been
573 deprecated. As described in :ghpull:`1167`, the complexity and confusion of
573 deprecated. As described in :ghpull:`1167`, the complexity and confusion of
574 migrating to this variable is not worth the aesthetic improvement. Please use
574 migrating to this variable is not worth the aesthetic improvement. Please use
575 the historical :envvar:`IPYTHONDIR` environment variable instead.
575 the historical :envvar:`IPYTHONDIR` environment variable instead.
576
576
577 * The default value of *interactivity* passed from
577 * The default value of *interactivity* passed from
578 :meth:`~IPython.core.interactiveshell.InteractiveShell.run_cell` to
578 :meth:`~IPython.core.interactiveshell.InteractiveShell.run_cell` to
579 :meth:`~IPython.core.interactiveshell.InteractiveShell.run_ast_nodes`
579 :meth:`~IPython.core.interactiveshell.InteractiveShell.run_ast_nodes`
580 is now configurable.
580 is now configurable.
581
581
582 * New ``%alias_magic`` function to conveniently create aliases of existing
582 * New ``%alias_magic`` function to conveniently create aliases of existing
583 magics, if you prefer to have shorter names for personal use.
583 magics, if you prefer to have shorter names for personal use.
584
584
585 * We ship unminified versions of the JavaScript libraries we use, to better
585 * We ship unminified versions of the JavaScript libraries we use, to better
586 comply with Debian's packaging policies.
586 comply with Debian's packaging policies.
587
587
588 * Simplify the information presented by ``obj?/obj??`` to eliminate a few
588 * Simplify the information presented by ``obj?/obj??`` to eliminate a few
589 redundant fields when possible. :ghpull:`2038`.
589 redundant fields when possible. :ghpull:`2038`.
590
590
591 * Improved continuous integration for IPython. We now have automated test runs
591 * Improved continuous integration for IPython. We now have automated test runs
592 on `Shining Panda <https://jenkins.shiningpanda.com/ipython>`_ and `Travis-CI
592 on `Shining Panda <https://jenkins.shiningpanda.com/ipython>`_ and `Travis-CI
593 <http://travis-ci.org/#!/ipython/ipython>`_, as well as `Tox support
593 <http://travis-ci.org/#!/ipython/ipython>`_, as well as `Tox support
594 <http://tox.testrun.org>`_.
594 <http://tox.testrun.org>`_.
595
595
596 * The `vim-ipython`_ functionality (externally developed) has been updated to
596 * The `vim-ipython`_ functionality (externally developed) has been updated to
597 the latest version.
597 the latest version.
598
598
599 .. _vim-ipython: https://github.com/ivanov/vim-ipython
599 .. _vim-ipython: https://github.com/ivanov/vim-ipython
600
600
601 * The ``%save`` magic now has a ``-f`` flag to force overwriting, which makes
601 * The ``%save`` magic now has a ``-f`` flag to force overwriting, which makes
602 it much more usable in the notebook where it is not possible to reply to
602 it much more usable in the notebook where it is not possible to reply to
603 interactive questions from the kernel. :ghpull:`1937`.
603 interactive questions from the kernel. :ghpull:`1937`.
604
604
605 * Use dvipng to format sympy.Matrix, enabling display of matrices in the Qt
605 * Use dvipng to format sympy.Matrix, enabling display of matrices in the Qt
606 console with the sympy printing extension. :ghpull:`1861`.
606 console with the sympy printing extension. :ghpull:`1861`.
607
607
608 * Our messaging protocol now has a reasonable test suite, helping ensure that
608 * Our messaging protocol now has a reasonable test suite, helping ensure that
609 we don't accidentally deviate from the spec and possibly break third-party
609 we don't accidentally deviate from the spec and possibly break third-party
610 applications that may have been using it. We encourage users to contribute
610 applications that may have been using it. We encourage users to contribute
611 more stringent tests to this part of the test suite. :ghpull:`1627`.
611 more stringent tests to this part of the test suite. :ghpull:`1627`.
612
612
613 * Use LaTeX to display, on output, various built-in types with the SymPy
613 * Use LaTeX to display, on output, various built-in types with the SymPy
614 printing extension. :ghpull:`1399`.
614 printing extension. :ghpull:`1399`.
615
615
616 * Add Gtk3 event loop integration and example. :ghpull:`1588`.
616 * Add Gtk3 event loop integration and example. :ghpull:`1588`.
617
617
618 * ``clear_output`` improvements, which allow things like progress bars and other
618 * ``clear_output`` improvements, which allow things like progress bars and other
619 simple animations to work well in the notebook (:ghpull:`1563`):
619 simple animations to work well in the notebook (:ghpull:`1563`):
620
620
621 * `clear_output()` clears the line, even in terminal IPython, the QtConsole
621 * `clear_output()` clears the line, even in terminal IPython, the QtConsole
622 and plain Python as well, by printing `\r` to streams.
622 and plain Python as well, by printing `\r` to streams.
623
623
624 * `clear_output()` avoids the flicker in the notebook by adding a delay,
624 * `clear_output()` avoids the flicker in the notebook by adding a delay,
625 and firing immediately upon the next actual display message.
625 and firing immediately upon the next actual display message.
626
626
627 * `display_javascript` hides its `output_area` element, so using display to
627 * `display_javascript` hides its `output_area` element, so using display to
628 run a bunch of javascript doesn't result in ever-growing vertical space.
628 run a bunch of javascript doesn't result in ever-growing vertical space.
629
629
630 * Add simple support for running inside a virtualenv. While this doesn't
630 * Add simple support for running inside a virtualenv. While this doesn't
631 supplant proper installation (as users should do), it helps ad-hoc calling of
631 supplant proper installation (as users should do), it helps ad-hoc calling of
632 IPython from inside a virtualenv. :ghpull:`1388`.
632 IPython from inside a virtualenv. :ghpull:`1388`.
633
633
634
634
635 Major Bugs fixed
635 Major Bugs fixed
636 ----------------
636 ----------------
637
637
638 In this cycle, we have :ref:`closed over 740 issues <issues_list_013>`, but a
638 In this cycle, we have :ref:`closed over 740 issues <issues_list_013>`, but a
639 few major ones merit special mention:
639 few major ones merit special mention:
640
640
641 * The ``%pastebin`` magic has been updated to point to gist.github.com, since
641 * The ``%pastebin`` magic has been updated to point to gist.github.com, since
642 unfortunately http://paste.pocoo.org has closed down. We also added a -d flag
642 unfortunately http://paste.pocoo.org has closed down. We also added a -d flag
643 for the user to provide a gist description string. :ghpull:`1670`.
643 for the user to provide a gist description string. :ghpull:`1670`.
644
644
645 * Fix ``%paste`` that would reject certain valid inputs. :ghpull:`1258`.
645 * Fix ``%paste`` that would reject certain valid inputs. :ghpull:`1258`.
646
646
647 * Fix sending and receiving of Numpy structured arrays (those with composite
647 * Fix sending and receiving of Numpy structured arrays (those with composite
648 dtypes, often used as recarrays). :ghpull:`2034`.
648 dtypes, often used as recarrays). :ghpull:`2034`.
649
649
650 * Reconnect when the websocket connection closes unexpectedly. :ghpull:`1577`.
650 * Reconnect when the websocket connection closes unexpectedly. :ghpull:`1577`.
651
651
652 * Fix truncated representation of objects in the debugger by showing at least
652 * Fix truncated representation of objects in the debugger by showing at least
653 80 characters' worth of information. :ghpull:`1793`.
653 80 characters' worth of information. :ghpull:`1793`.
654
654
655 * Fix logger to be Unicode-aware: logging could crash ipython if there was
655 * Fix logger to be Unicode-aware: logging could crash ipython if there was
656 unicode in the input. :ghpull:`1792`.
656 unicode in the input. :ghpull:`1792`.
657
657
658 * Fix images missing from XML/SVG export in the Qt console. :ghpull:`1449`.
658 * Fix images missing from XML/SVG export in the Qt console. :ghpull:`1449`.
659
659
660 * Fix deepreload on Python 3. :ghpull:`1625`, as well as having a much cleaner
660 * Fix deepreload on Python 3. :ghpull:`1625`, as well as having a much cleaner
661 and more robust implementation of deepreload in general. :ghpull:`1457`.
661 and more robust implementation of deepreload in general. :ghpull:`1457`.
662
662
663
663
664 Backwards incompatible changes
664 Backwards incompatible changes
665 ------------------------------
665 ------------------------------
666
666
667 * The exception :exc:`IPython.core.error.TryNext` previously accepted
667 * The exception :exc:`IPython.core.error.TryNext` previously accepted
668 arguments and keyword arguments to be passed to the next implementation
668 arguments and keyword arguments to be passed to the next implementation
669 of the hook. This feature was removed as it made error message propagation
669 of the hook. This feature was removed as it made error message propagation
670 difficult and violated the principle of loose coupling.
670 difficult and violated the principle of loose coupling.
1 NO CONTENT: modified file
NO CONTENT: modified file
@@ -1,215 +1,215 b''
1 ============
1 ============
2 7.x Series
2 7.x Series
3 ============
3 ============
4
4
5 .. _whatsnew700:
5 .. _whatsnew700:
6
6
7 IPython 7.0.0
7 IPython 7.0.0
8 =============
8 =============
9
9
10 .. warning::
10 .. warning::
11
11
12 IPython 7.0 is currently in Beta, Feedback on API/changes and
12 IPython 7.0 is currently in Beta, Feedback on API/changes and
13 addition/updates to this cahngelog are welcomed.
13 addition/updates to this cahngelog are welcomed.
14
14
15 Released .... ...., 2017
15 Released .... ...., 2017
16
16
17 IPython 7 include major features improvement as you can read in the following
17 IPython 7 include major features improvement as you can read in the following
18 changelog. This is also the second major version of IPython to stop support only
18 changelog. This is also the second major version of IPython to stop support only
19 Python 3 – starting at Python 3.4. Python 2 is still still community supported
19 Python 3 – starting at Python 3.4. Python 2 is still still community supported
20 on the bugfix only 5.x branch, but we remind you that Python 2 EOL is Jan 1st
20 on the bugfix only 5.x branch, but we remind you that Python 2 EOL is Jan 1st
21 2020.
21 2020.
22
22
23 We were able to backport bug fixes to the 5.x branch thanks to our backport bot which
23 We were able to backport bug fixes to the 5.x branch thanks to our backport bot which
24 backported more than `70 Pull-Requests
24 backported more than `70 Pull-Requests
25 <https://github.com/ipython/ipython/pulls?page=3&q=is%3Apr+sort%3Aupdated-desc+author%3Aapp%2Fmeeseeksdev++5.x&utf8=%E2%9C%93>`_, but there are still many PRs that required manually work, and this is an area of the project were you can easily contribute by looking for `PRs still needed backport <https://github.com/ipython/ipython/issues?q=label%3A%22Still+Needs+Manual+Backport%22+is%3Aclosed+sort%3Aupdated-desc>`_
25 <https://github.com/ipython/ipython/pulls?page=3&q=is%3Apr+sort%3Aupdated-desc+author%3Aapp%2Fmeeseeksdev++5.x&utf8=%E2%9C%93>`_, but there are still many PRs that required manually work, and this is an area of the project were you can easily contribute by looking for `PRs still needed backport <https://github.com/ipython/ipython/issues?q=label%3A%22Still+Needs+Manual+Backport%22+is%3Aclosed+sort%3Aupdated-desc>`_
26
26
27 IPython 6.x branch will likely not see any further release unless we critical
27 IPython 6.x branch will likely not see any further release unless we critical
28 bugs are found.
28 bugs are found.
29
29
30 Make sure you have pip > 9.0 before upgrading. You should be able to update by simply runngin
30 Make sure you have pip > 9.0 before upgrading. You should be able to update by simply runngin
31
31
32 .. code::
32 .. code::
33
33
34 pip install ipython --upgrade
34 pip install ipython --upgrade
35
35
36 Or if you have conda installed:
36 Or if you have conda installed:
37
37
38 .. code::
38 .. code::
39
39
40 conda install ipython
40 conda install ipython
41
41
42
42
43
43
44 Prompt Toolkit 2.0
44 Prompt Toolkit 2.0
45 ------------------
45 ------------------
46
46
47 IPython 7.0+ now use ``prompt_toolkit 2.0``, if you still need to use earlier
47 IPython 7.0+ now use ``prompt_toolkit 2.0``, if you still need to use earlier
48 ``prompt_toolkit`` version you may need to pin IPython to ``<7.0``.
48 ``prompt_toolkit`` version you may need to pin IPython to ``<7.0``.
49
49
50 Autowait: Asynchronous REPL
50 Autowait: Asynchronous REPL
51 ---------------------------
51 ---------------------------
52
52
53 Staring with IPython 7.0 and on Python 3.6+, IPython can automatically await
53 Staring with IPython 7.0 and on Python 3.6+, IPython can automatically await
54 code at top level, you should not need to access an event loop or runner
54 code at top level, you should not need to access an event loop or runner
55 yourself. To know more read the :ref:`autoawait` section of our docs, see
55 yourself. To know more read the :ref:`autoawait` section of our docs, see
56 :ghpull:`11265` or try the following code::
56 :ghpull:`11265` or try the following code::
57
57
58 Python 3.6.0
58 Python 3.6.0
59 Type 'copyright', 'credits' or 'license' for more information
59 Type 'copyright', 'credits' or 'license' for more information
60 IPython 7.0.0 -- An enhanced Interactive Python. Type '?' for help.
60 IPython 7.0.0 -- An enhanced Interactive Python. Type '?' for help.
61
61
62 In [1]: import aiohttp
62 In [1]: import aiohttp
63 ...: result = aiohttp.get('https://api.github.com')
63 ...: result = aiohttp.get('https://api.github.com')
64
64
65 In [2]: response = await result
65 In [2]: response = await result
66 <pause for a few 100s ms>
66 <pause for a few 100s ms>
67
67
68 In [3]: await response.json()
68 In [3]: await response.json()
69 Out[3]:
69 Out[3]:
70 {'authorizations_url': 'https://api.github.com/authorizations',
70 {'authorizations_url': 'https://api.github.com/authorizations',
71 'code_search_url': 'https://api.github.com/search/code?q={query}{&page,per_page,sort,order}',
71 'code_search_url': 'https://api.github.com/search/code?q={query}{&page,per_page,sort,order}',
72 ...
72 ...
73 }
73 }
74
74
75 .. note::
75 .. note::
76
76
77 Async integration is experimental code, behavior may change or be removed
77 Async integration is experimental code, behavior may change or be removed
78 between Python and IPython versions without warnings.
78 between Python and IPython versions without warnings.
79
79
80 Integration is by default with `asyncio`, but other libraries can be configured,
80 Integration is by default with `asyncio`, but other libraries can be configured,
81 like ``curio`` or ``trio``, to improve concurrency in the REPL::
81 like ``curio`` or ``trio``, to improve concurrency in the REPL::
82
82
83 In [1]: %autoawait trio
83 In [1]: %autoawait trio
84
84
85 In [2]: import trio
85 In [2]: import trio
86
86
87 In [3]: async def child(i):
87 In [3]: async def child(i):
88 ...: print(" child %s goes to sleep"%i)
88 ...: print(" child %s goes to sleep"%i)
89 ...: await trio.sleep(2)
89 ...: await trio.sleep(2)
90 ...: print(" child %s wakes up"%i)
90 ...: print(" child %s wakes up"%i)
91
91
92 In [4]: print('parent start')
92 In [4]: print('parent start')
93 ...: async with trio.open_nursery() as n:
93 ...: async with trio.open_nursery() as n:
94 ...: for i in range(3):
94 ...: for i in range(3):
95 ...: n.spawn(child, i)
95 ...: n.spawn(child, i)
96 ...: print('parent end')
96 ...: print('parent end')
97 parent start
97 parent start
98 child 2 goes to sleep
98 child 2 goes to sleep
99 child 0 goes to sleep
99 child 0 goes to sleep
100 child 1 goes to sleep
100 child 1 goes to sleep
101 <about 2 seconds pause>
101 <about 2 seconds pause>
102 child 2 wakes up
102 child 2 wakes up
103 child 1 wakes up
103 child 1 wakes up
104 child 0 wakes up
104 child 0 wakes up
105 parent end
105 parent end
106
106
107 See :ref:`autoawait` for more information.
107 See :ref:`autoawait` for more information.
108
108
109
109
110 Asynchronous code in a Notebook interface or any other frontend using the
110 Asynchronous code in a Notebook interface or any other frontend using the
111 Jupyter Protocol will need further updates of the IPykernel package.
111 Jupyter Protocol will need further updates of the IPykernel package.
112
112
113 Non-Asynchronous code
113 Non-Asynchronous code
114 ~~~~~~~~~~~~~~~~~~~~~
114 ~~~~~~~~~~~~~~~~~~~~~
115
115
116 As the internal API of IPython are now asynchronous, IPython need to run under
116 As the internal API of IPython are now asynchronous, IPython need to run under
117 an even loop. In order to allow many workflow, (like using the ``%run`` magic,
117 an even loop. In order to allow many workflow, (like using the ``%run`` magic,
118 or copy_pasting code that explicitly starts/stop event loop), when top-level code
118 or copy_pasting code that explicitly starts/stop event loop), when top-level code
119 is detected as not being asynchronous, IPython code is advanced via a
119 is detected as not being asynchronous, IPython code is advanced via a
120 pseudo-synchronous runner, and will not may not advance pending tasks.
120 pseudo-synchronous runner, and will not may not advance pending tasks.
121
121
122 Change to Nested Embed
122 Change to Nested Embed
123 ~~~~~~~~~~~~~~~~~~~~~~
123 ~~~~~~~~~~~~~~~~~~~~~~
124
124
125 The introduction of the ability to run async code had some effect on the
125 The introduction of the ability to run async code had some effect on the
126 ``IPython.embed()`` API. By default embed will not allow you to run asynchronous
126 ``IPython.embed()`` API. By default embed will not allow you to run asynchronous
127 code unless a event loop is specified.
127 code unless a event loop is specified.
128
128
129 Effects on Magics
129 Effects on Magics
130 ~~~~~~~~~~~~~~~~~
130 ~~~~~~~~~~~~~~~~~
131
131
132 Some magics will not work with Async, and will need updates. Contribution
132 Some magics will not work with Async, and will need updates. Contribution
133 welcome.
133 welcome.
134
134
135 Expected Future changes
135 Expected Future changes
136 ~~~~~~~~~~~~~~~~~~~~~~~
136 ~~~~~~~~~~~~~~~~~~~~~~~
137
137
138 We expect more internal but public IPython function to become ``async``, and
138 We expect more internal but public IPython function to become ``async``, and
139 will likely end up having a persisting event loop while IPython is running.
139 will likely end up having a persisting event loop while IPython is running.
140
140
141 Thanks
141 Thanks
142 ~~~~~~
142 ~~~~~~
143
143
144 This took more than a year in the making, and the code was rebased a number of
144 This took more than a year in the making, and the code was rebased a number of
145 time leading to commit authorship that may have been lost in the final
145 time leading to commit authorship that may have been lost in the final
146 Pull-Request. Huge thanks to many people for contribution, discussion, code,
146 Pull-Request. Huge thanks to many people for contribution, discussion, code,
147 documentation, use-case: dalejung, danielballan, ellisonbg, fperez, gnestor,
147 documentation, use-case: dalejung, danielballan, ellisonbg, fperez, gnestor,
148 minrk, njsmith, pganssle, tacaswell, takluyver , vidartf ... And many other.
148 minrk, njsmith, pganssle, tacaswell, takluyver , vidartf ... And many other.
149
149
150
150
151 Autoreload Improvment
151 Autoreload Improvement
152 ---------------------
152 ----------------------
153
153
154 The magic ``%autoreload 2`` now captures new methods added to classes. Earlier, only methods existing as of the initial import were being tracked and updated.
154 The magic ``%autoreload 2`` now captures new methods added to classes. Earlier, only methods existing as of the initial import were being tracked and updated.
155
155
156 This new feature helps dual environment development - Jupyter+IDE - where the code gradually moves from notebook cells to package files, as it gets structured.
156 This new feature helps dual environment development - Jupyter+IDE - where the code gradually moves from notebook cells to package files, as it gets structured.
157
157
158 **Example**: An instance of the class `MyClass` will be able to access the method `cube()` after it is uncommented and the file `file1.py` saved on disk.
158 **Example**: An instance of the class `MyClass` will be able to access the method `cube()` after it is uncommented and the file `file1.py` saved on disk.
159
159
160
160
161 ..code::
161 ..code::
162
162
163 # notebook
163 # notebook
164
164
165 from mymodule import MyClass
165 from mymodule import MyClass
166 first = MyClass(5)
166 first = MyClass(5)
167
167
168 .. code::
168 .. code::
169
169
170 # mymodule/file1.py
170 # mymodule/file1.py
171
171
172 class MyClass:
172 class MyClass:
173
173
174 def __init__(self, a=10):
174 def __init__(self, a=10):
175 self.a = a
175 self.a = a
176
176
177 def square(self):
177 def square(self):
178 print('compute square')
178 print('compute square')
179 return self.a*self.a
179 return self.a*self.a
180
180
181 # def cube(self):
181 # def cube(self):
182 # print('compute cube')
182 # print('compute cube')
183 # return self.a*self.a*self.a
183 # return self.a*self.a*self.a
184
184
185
185
186
186
187
187
188 Misc
188 Misc
189 ----
189 ----
190
190
191 The autoindent feature that was deprecated in 5.x was re-enabled and
191 The autoindent feature that was deprecated in 5.x was re-enabled and
192 un-deprecated in :ghpull:`11257`
192 un-deprecated in :ghpull:`11257`
193
193
194 Make ``%run -n -i ...`` work correctly. Earlier, if ``%run`` was passed both arguments, ``-n`` would be silently ignored. See :ghpull:`10308`
194 Make ``%run -n -i ...`` work correctly. Earlier, if ``%run`` was passed both arguments, ``-n`` would be silently ignored. See :ghpull:`10308`
195
195
196
196
197
197
198
198
199
199
200 Deprecations
200 Deprecations
201 ------------
201 ------------
202
202
203 A couple of unused function and methods have been deprecated and will be removed
203 A couple of unused function and methods have been deprecated and will be removed
204 in future versions:
204 in future versions:
205
205
206 - ``IPython.utils.io.raw_print_err``
206 - ``IPython.utils.io.raw_print_err``
207 - ``IPython.utils.io.raw_print``
207 - ``IPython.utils.io.raw_print``
208
208
209
209
210 Backwards incompatible changes
210 Backwards incompatible changes
211 ------------------------------
211 ------------------------------
212
212
213 * The API for transforming input before it is parsed as Python code has been
213 * The API for transforming input before it is parsed as Python code has been
214 completely redesigned, and any custom input transformations will need to be
214 completely redesigned, and any custom input transformations will need to be
215 rewritten. See :doc:`/config/inputtransforms` for details of the new API.
215 rewritten. See :doc:`/config/inputtransforms` for details of the new API.
General Comments 0
You need to be logged in to leave comments. Login now