Show More
@@ -147,10 +147,7 b' var IPython = (function (IPython) {' | |||
|
147 | 147 | } |
|
148 | 148 | if (this.code_mirror) { |
|
149 | 149 | this.code_mirror.on('blur', function(cm, change) { |
|
150 | // Check if this unfocus event is legit. | |
|
151 | if (!that.should_cancel_blur()) { | |
|
152 | 150 |
|
|
153 | } | |
|
154 | 151 | }); |
|
155 | 152 | } |
|
156 | 153 | }; |
@@ -333,17 +330,6 b' var IPython = (function (IPython) {' | |||
|
333 | 330 | }; |
|
334 | 331 | |
|
335 | 332 | /** |
|
336 | * Determine whether or not the unfocus event should be aknowledged. | |
|
337 | * | |
|
338 | * @method should_cancel_blur | |
|
339 | * | |
|
340 | * @return results {bool} Whether or not to ignore the cell's blur event. | |
|
341 | **/ | |
|
342 | Cell.prototype.should_cancel_blur = function () { | |
|
343 | return false; | |
|
344 | }; | |
|
345 | ||
|
346 | /** | |
|
347 | 333 | * Focus the cell in the DOM sense |
|
348 | 334 | * @method focus_cell |
|
349 | 335 | */ |
@@ -358,21 +358,6 b' var IPython = (function (IPython) {' | |||
|
358 | 358 | return false; |
|
359 | 359 | }; |
|
360 | 360 | |
|
361 | /** | |
|
362 | * Determine whether or not the unfocus event should be aknowledged. | |
|
363 | * | |
|
364 | * @method should_cancel_blur | |
|
365 | * | |
|
366 | * @return results {bool} Whether or not to ignore the cell's blur event. | |
|
367 | **/ | |
|
368 | CodeCell.prototype.should_cancel_blur = function () { | |
|
369 | // Cancel this unfocus event if the base wants to cancel or the cell | |
|
370 | // completer is open or the tooltip is open. | |
|
371 | return IPython.Cell.prototype.should_cancel_blur.apply(this) || | |
|
372 | (this.completer && this.completer.is_visible()) || | |
|
373 | (IPython.tooltip && IPython.tooltip.is_visible()); | |
|
374 | }; | |
|
375 | ||
|
376 | 361 | CodeCell.prototype.select_all = function () { |
|
377 | 362 | var start = {line: 0, ch: 0}; |
|
378 | 363 | var nlines = this.code_mirror.lineCount(); |
@@ -508,6 +493,23 b' var IPython = (function (IPython) {' | |||
|
508 | 493 | return data; |
|
509 | 494 | }; |
|
510 | 495 | |
|
496 | /** | |
|
497 | * handle cell level logic when a cell is unselected | |
|
498 | * @method unselect | |
|
499 | * @return is the action being taken | |
|
500 | */ | |
|
501 | CodeCell.prototype.unselect = function () { | |
|
502 | var cont = IPython.Cell.prototype.unselect.apply(this); | |
|
503 | if (cont) { | |
|
504 | // When a code cell is usnelected, make sure that the corresponding | |
|
505 | // tooltip and completer to that cell is closed. | |
|
506 | IPython.tooltip.remove_and_cancel_tooltip(true); | |
|
507 | if (this.completer !== null) { | |
|
508 | this.completer.close(); | |
|
509 | } | |
|
510 | } | |
|
511 | return cont; | |
|
512 | }; | |
|
511 | 513 | |
|
512 | 514 | IPython.CodeCell = CodeCell; |
|
513 | 515 |
@@ -73,7 +73,6 b' var IPython = (function (IPython) {' | |||
|
73 | 73 | |
|
74 | 74 | |
|
75 | 75 | var Completer = function (cell) { |
|
76 | this._visible = false; | |
|
77 | 76 | this.cell = cell; |
|
78 | 77 | this.editor = cell.code_mirror; |
|
79 | 78 | var that = this; |
@@ -85,15 +84,9 b' var IPython = (function (IPython) {' | |||
|
85 | 84 | }); |
|
86 | 85 | }; |
|
87 | 86 | |
|
88 | Completer.prototype.is_visible = function () { | |
|
89 | // Return whether or not the completer is visible. | |
|
90 | return this._visible; | |
|
91 | }; | |
|
92 | ||
|
93 | 87 | Completer.prototype.startCompletion = function () { |
|
94 | 88 | // call for a 'first' completion, that will set the editor and do some |
|
95 |
// special behavio |
|
|
96 | // | |
|
89 | // special behavior like autopicking if only one completion available. | |
|
97 | 90 | if (this.editor.somethingSelected()) return; |
|
98 | 91 | this.done = false; |
|
99 | 92 | // use to get focus back on opera |
@@ -221,18 +214,38 b' var IPython = (function (IPython) {' | |||
|
221 | 214 | } |
|
222 | 215 | } |
|
223 | 216 | |
|
217 | if (!this.visible) { | |
|
224 | 218 | this.complete = $('<div/>').addClass('completions'); |
|
225 | 219 | this.complete.attr('id', 'complete'); |
|
226 | 220 | |
|
227 | 221 | // Currently webkit doesn't use the size attr correctly. See: |
|
228 | 222 | // https://code.google.com/p/chromium/issues/detail?id=4579 |
|
229 |
this.sel = $('<select |
|
|
230 |
.attr(' |
|
|
231 | .attr('size', Math.min(10, this.raw_result.length)); | |
|
223 | this.sel = $('<select/>') | |
|
224 | .attr('tabindex', -1) | |
|
225 | .attr('multiple', 'true'); | |
|
232 | 226 | this.complete.append(this.sel); |
|
233 |
this. |
|
|
227 | this.visible = true; | |
|
234 | 228 | $('body').append(this.complete); |
|
235 | 229 | |
|
230 | //build the container | |
|
231 | var that = this; | |
|
232 | this.sel.dblclick(function () { | |
|
233 | that.pick(); | |
|
234 | }); | |
|
235 | this.sel.focus(function () { | |
|
236 | that.editor.focus(); | |
|
237 | }); | |
|
238 | this._handle_keydown = function (cm, event) { | |
|
239 | that.keydown(event); | |
|
240 | }; | |
|
241 | this.editor.on('keydown', this._handle_keydown); | |
|
242 | this._handle_keypress = function (cm, event) { | |
|
243 | that.keypress(event); | |
|
244 | }; | |
|
245 | this.editor.on('keypress', this._handle_keypress); | |
|
246 | } | |
|
247 | this.sel.attr('size', Math.min(10, this.raw_result.length)); | |
|
248 | ||
|
236 | 249 | // After everything is on the page, compute the postion. |
|
237 | 250 | // We put it above the code if it is too close to the bottom of the page. |
|
238 | 251 | cur.ch = cur.ch-matched_text.length; |
@@ -249,28 +262,9 b' var IPython = (function (IPython) {' | |||
|
249 | 262 | this.complete.css('left', left + 'px'); |
|
250 | 263 | this.complete.css('top', top + 'px'); |
|
251 | 264 | |
|
252 | ||
|
253 | //build the container | |
|
254 | var that = this; | |
|
255 | this.sel.dblclick(function () { | |
|
256 | that.pick(); | |
|
257 | }); | |
|
258 | this.sel.blur(this.close); | |
|
259 | this.sel.keydown(function (event) { | |
|
260 | that.keydown(event); | |
|
261 | }); | |
|
262 | this.sel.keypress(function (event) { | |
|
263 | that.keypress(event); | |
|
264 | }); | |
|
265 | ||
|
265 | // Clear and fill the list. | |
|
266 | this.sel.text(''); | |
|
266 | 267 | this.build_gui_list(this.raw_result); |
|
267 | ||
|
268 | this.sel.focus(); | |
|
269 | IPython.keyboard_manager.disable(); | |
|
270 | // Opera sometimes ignores focusing a freshly created node | |
|
271 | if (window.opera) setTimeout(function () { | |
|
272 | if (!this.done) this.sel.focus(); | |
|
273 | }, 100); | |
|
274 | 268 | return true; |
|
275 | 269 | }; |
|
276 | 270 | |
@@ -288,20 +282,16 b' var IPython = (function (IPython) {' | |||
|
288 | 282 | }; |
|
289 | 283 | |
|
290 | 284 | Completer.prototype.close = function () { |
|
291 | this._visible = false; | |
|
292 | if (this.done) return; | |
|
293 | 285 | this.done = true; |
|
294 |
$(' |
|
|
295 | IPython.keyboard_manager.enable(); | |
|
286 | $('#complete').remove(); | |
|
287 | this.editor.off('keydown', this._handle_keydown); | |
|
288 | this.editor.off('keypress', this._handle_keypress); | |
|
289 | this.visible = false; | |
|
296 | 290 | }; |
|
297 | 291 | |
|
298 | 292 | Completer.prototype.pick = function () { |
|
299 | 293 | this.insert(this.raw_result[this.sel[0].selectedIndex]); |
|
300 | 294 | this.close(); |
|
301 | var that = this; | |
|
302 | setTimeout(function () { | |
|
303 | that.editor.focus(); | |
|
304 | }, 50); | |
|
305 | 295 | }; |
|
306 | 296 | |
|
307 | 297 | Completer.prototype.keydown = function (event) { |
@@ -312,16 +302,10 b' var IPython = (function (IPython) {' | |||
|
312 | 302 | if (code == keycodes.enter) { |
|
313 | 303 | CodeMirror.e_stop(event); |
|
314 | 304 | this.pick(); |
|
315 | } | |
|
316 | 305 | // Escape or backspace |
|
317 | else if (code == keycodes.esc) { | |
|
306 | } else if (code == keycodes.esc || code == keycodes.backspace) { | |
|
318 | 307 | CodeMirror.e_stop(event); |
|
319 | 308 | this.close(); |
|
320 | this.editor.focus(); | |
|
321 | ||
|
322 | } else if (code == keycodes.backspace) { | |
|
323 | this.close(); | |
|
324 | this.editor.focus(); | |
|
325 | 309 | } else if (code == keycodes.tab) { |
|
326 | 310 | //all the fastforwarding operation, |
|
327 | 311 | //Check that shared start is not null which can append with prefixed completion |
@@ -332,8 +316,6 b' var IPython = (function (IPython) {' | |||
|
332 | 316 | this.insert(sh); |
|
333 | 317 | } |
|
334 | 318 | this.close(); |
|
335 | CodeMirror.e_stop(event); | |
|
336 | this.editor.focus(); | |
|
337 | 319 | //reinvoke self |
|
338 | 320 | setTimeout(function () { |
|
339 | 321 | that.carry_on_completion(); |
@@ -341,7 +323,20 b' var IPython = (function (IPython) {' | |||
|
341 | 323 | } else if (code == keycodes.up || code == keycodes.down) { |
|
342 | 324 | // need to do that to be able to move the arrow |
|
343 | 325 | // when on the first or last line ofo a code cell |
|
344 | event.stopPropagation(); | |
|
326 | CodeMirror.e_stop(event); | |
|
327 | ||
|
328 | var options = this.sel.find('option'); | |
|
329 | var index = this.sel[0].selectedIndex; | |
|
330 | if (code == keycodes.up) { | |
|
331 | index--; | |
|
332 | } | |
|
333 | if (code == keycodes.down) { | |
|
334 | index++; | |
|
335 | } | |
|
336 | index = Math.min(Math.max(index, 0), options.length-1); | |
|
337 | this.sel[0].selectedIndex = index; | |
|
338 | } else if (code == keycodes.left || code == keycodes.right) { | |
|
339 | this.close(); | |
|
345 | 340 | } |
|
346 | 341 | }; |
|
347 | 342 | |
@@ -358,26 +353,16 b' var IPython = (function (IPython) {' | |||
|
358 | 353 | // don't handle keypress if it's not a character (arrows on FF) |
|
359 | 354 | // or ENTER/TAB |
|
360 | 355 | if (event.charCode === 0 || |
|
361 |
code == keycodes. |
|
|
362 |
code == keycodes. |
|
|
356 | code == keycodes.tab || | |
|
357 | code == keycodes.enter | |
|
363 | 358 | ) return; |
|
364 | 359 | |
|
365 | var cur = this.editor.getCursor(); | |
|
366 | var completion = { | |
|
367 | str: String.fromCharCode(event.which), | |
|
368 | type: "introspection", | |
|
369 | from: cur, | |
|
370 | to: cur, | |
|
371 | }; | |
|
372 | this.insert(completion); | |
|
373 | ||
|
374 | 360 | this.close(); |
|
375 | 361 | this.editor.focus(); |
|
376 | 362 | setTimeout(function () { |
|
377 | 363 | that.carry_on_completion(); |
|
378 | 364 | }, 50); |
|
379 | 365 | }; |
|
380 | ||
|
381 | 366 | IPython.Completer = Completer; |
|
382 | 367 | |
|
383 | 368 | return IPython; |
@@ -17,6 +17,7 b'' | |||
|
17 | 17 | font-family: @monoFontFamily; |
|
18 | 18 | font-size: 110%; |
|
19 | 19 | color: @textColor; |
|
20 | width: auto; | |
|
20 | 21 | } |
|
21 | 22 | |
|
22 | 23 | .completions select option.context { |
@@ -1,7 +1,3 b'' | |||
|
1 | .clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0} | |
|
2 | .clearfix:after{clear:both} | |
|
3 | .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0} | |
|
4 | .input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} | |
|
5 | 1 | article,aside,details,figcaption,figure,footer,header,hgroup,nav,section{display:block} |
|
6 | 2 | audio,canvas,video{display:inline-block;*display:inline;*zoom:1} |
|
7 | 3 | audio:not([controls]){display:none} |
@@ -856,6 +852,10 b' a.label:hover,a.label:focus,a.badge:hover,a.badge:focus{color:#fff;text-decorati' | |||
|
856 | 852 | .show{display:block} |
|
857 | 853 | .invisible{visibility:hidden} |
|
858 | 854 | .affix{position:fixed} |
|
855 | .clearfix{*zoom:1}.clearfix:before,.clearfix:after{display:table;content:"";line-height:0} | |
|
856 | .clearfix:after{clear:both} | |
|
857 | .hide-text{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0} | |
|
858 | .input-block-level{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box} | |
|
859 | 859 | @-ms-viewport{width:device-width}.hidden{display:none;visibility:hidden} |
|
860 | 860 | .visible-phone{display:none !important} |
|
861 | 861 | .visible-tablet{display:none !important} |
@@ -1497,7 +1497,7 b' p{margin-bottom:0}' | |||
|
1497 | 1497 | .celltoolbar input[type=checkbox]{margin:0;margin-left:4px;margin-right:4px} |
|
1498 | 1498 | .celltoolbar .ui-button{border:none;vertical-align:top;height:20px;min-width:30px} |
|
1499 | 1499 | .completions{position:absolute;z-index:10;overflow:hidden;border:1px solid #ababab;border-radius:4px;-webkit-box-shadow:0 6px 10px -1px #adadad;-moz-box-shadow:0 6px 10px -1px #adadad;box-shadow:0 6px 10px -1px #adadad} |
|
1500 | .completions select{background:#fff;outline:none;border:none;padding:0;margin:0;overflow:auto;font-family:monospace;font-size:110%;color:#000} | |
|
1500 | .completions select{background:#fff;outline:none;border:none;padding:0;margin:0;overflow:auto;font-family:monospace;font-size:110%;color:#000;width:auto} | |
|
1501 | 1501 | .completions select option.context{color:#0064cd} |
|
1502 | 1502 | #menubar .navbar-inner{min-height:28px;border-top:1px;border-radius:0 0 4px 4px} |
|
1503 | 1503 | #menubar .navbar{margin-bottom:8px} |
@@ -83,6 +83,7 b' function(WidgetManager, _, Backbone){' | |||
|
83 | 83 | break; |
|
84 | 84 | case 'display': |
|
85 | 85 | this.widget_manager.display_view(msg, this); |
|
86 | this.trigger('displayed'); | |
|
86 | 87 | break; |
|
87 | 88 | } |
|
88 | 89 | }, |
@@ -29,16 +29,23 b' define(["widgets/js/widget"], function(WidgetManager){' | |||
|
29 | 29 | this.model.on('change:_children', function(model, value, options) { |
|
30 | 30 | this.update_children(model.previous('_children'), value); |
|
31 | 31 | }, this); |
|
32 | this.model.on('change:selected_index', function(model, value, options) { | |
|
33 | this.update_selected_index(model.previous('selected_index'), value, options); | |
|
34 | }, this); | |
|
35 | this.model.on('change:_titles', function(model, value, options) { | |
|
36 | this.update_titles(value); | |
|
37 | }, this); | |
|
38 | this.model.on('displayed', function() { | |
|
39 | this.update_titles(); | |
|
40 | }, this); | |
|
32 | 41 | }, |
|
33 | 42 | |
|
34 |
update: function( |
|
|
35 | // Update the contents of this view | |
|
36 | // | |
|
37 | // Called when the model is changed. The model may have been | |
|
38 | // changed by another view or by a state update from the back-end. | |
|
39 | if (options === undefined || options.updated_view != this) { | |
|
43 | update_titles: function(titles) { | |
|
40 | 44 |
|
|
41 | var titles = this.model.get('_titles'); | |
|
45 | if (!titles) { | |
|
46 | titles = this.model.get('_titles'); | |
|
47 | } | |
|
48 | ||
|
42 | 49 |
|
|
43 | 50 |
|
|
44 | 51 |
|
@@ -49,20 +56,17 b' define(["widgets/js/widget"], function(WidgetManager){' | |||
|
49 | 56 |
|
|
50 | 57 |
|
|
51 | 58 |
|
|
59 | }, | |
|
52 | 60 | |
|
53 | // Set selected page | |
|
54 | var selected_index = this.model.get("selected_index"); | |
|
55 | if (0 <= selected_index && selected_index < this.containers.length) { | |
|
56 | _.each(this.containers, function(container, index) { | |
|
57 | if (index==selected_index) { | |
|
58 | container.find('.accordion-body').collapse('show'); | |
|
59 | } else { | |
|
60 | container.find('.accordion-body').collapse('hide'); | |
|
61 | } | |
|
62 | }); | |
|
61 | update_selected_index: function(old_index, new_index, options) { | |
|
62 | // Only update the selection if the selection wasn't triggered | |
|
63 | // by the front-end. It must be triggered by the back-end. | |
|
64 | if (options === undefined || options.updated_view != this) { | |
|
65 | this.containers[old_index].find('.accordion-body').collapse('hide'); | |
|
66 | if (0 <= new_index && new_index < this.containers.length) { | |
|
67 | this.containers[new_index].find('.accordion-body').collapse('show'); | |
|
63 | 68 | } |
|
64 | 69 | } |
|
65 | return AccordionView.__super__.update.apply(this); | |
|
66 | 70 | }, |
|
67 | 71 | |
|
68 | 72 | update_children: function(old_list, new_list) { |
@@ -103,7 +107,7 b' define(["widgets/js/widget"], function(WidgetManager){' | |||
|
103 | 107 | |
|
104 | 108 | // Calling model.set will trigger all of the other views of the |
|
105 | 109 | // model to update. |
|
106 |
that.model.set("selected_index", index, {updated_view: th |
|
|
110 | that.model.set("selected_index", index, {updated_view: that}); | |
|
107 | 111 | that.touch(); |
|
108 | 112 | }) |
|
109 | 113 | .text('Page ' + index) |
@@ -120,12 +124,7 b' define(["widgets/js/widget"], function(WidgetManager){' | |||
|
120 | 124 | accordion_inner.append(view.$el); |
|
121 | 125 | |
|
122 | 126 | this.update(); |
|
123 | ||
|
124 | // Stupid workaround to close the bootstrap accordion tabs which | |
|
125 | // open by default even though they don't have the `in` class | |
|
126 | // attached to them. For some reason a delay is required. | |
|
127 | // TODO: Better fix. | |
|
128 | setTimeout(function(){ that.update(); }, 500); | |
|
127 | this.update_titles(); | |
|
129 | 128 | }, |
|
130 | 129 | }); |
|
131 | 130 | WidgetManager.register_widget_view('AccordionView', AccordionView); |
@@ -104,5 +104,10 b' casper.notebook_test(function () {' | |||
|
104 | 104 | this.execute_cell_then(index, function(index){ |
|
105 | 105 | this.test.assertEquals(this.get_output_cell(index).text, '1\n', // 0 based |
|
106 | 106 | 'selected_index property updated with tab change.'); |
|
107 | ||
|
108 | var is_collapsed = this.evaluate(function(s){ | |
|
109 | return $(s + ' div.accordion-group:nth-child(2) a').hasClass('collapsed'); // 1 based | |
|
110 | }, {s: multicontainer2_query}); | |
|
111 | this.test.assertEquals(is_collapsed, false, 'Was tab actually opened?'); | |
|
107 | 112 | }); |
|
108 | 113 | }); No newline at end of file |
@@ -304,7 +304,7 b' class Demo(object):' | |||
|
304 | 304 | self.src_blocks = src_blocks |
|
305 | 305 | |
|
306 | 306 | # also build syntax-highlighted source |
|
307 | self.src_blocks_colored = map(self.ip_colorize,self.src_blocks) | |
|
307 | self.src_blocks_colored = list(map(self.ip_colorize,self.src_blocks)) | |
|
308 | 308 | |
|
309 | 309 | # ensure clean namespace and seek offset |
|
310 | 310 | self.reset() |
@@ -593,7 +593,7 b' class SSHLauncher(LocalProcessLauncher):' | |||
|
593 | 593 | |
|
594 | 594 | def _send_file(self, local, remote): |
|
595 | 595 | """send a single file""" |
|
596 | remote = "%s:%s" % (self.location, remote) | |
|
596 | full_remote = "%s:%s" % (self.location, remote) | |
|
597 | 597 | for i in range(10): |
|
598 | 598 | if not os.path.exists(local): |
|
599 | 599 | self.log.debug("waiting for %s" % local) |
@@ -605,8 +605,8 b' class SSHLauncher(LocalProcessLauncher):' | |||
|
605 | 605 | check_output(self.ssh_cmd + self.ssh_args + \ |
|
606 | 606 | [self.location, 'mkdir', '-p', '--', remote_dir] |
|
607 | 607 | ) |
|
608 | self.log.info("sending %s to %s", local, remote) | |
|
609 | check_output(self.scp_cmd + [local, remote]) | |
|
608 | self.log.info("sending %s to %s", local, full_remote) | |
|
609 | check_output(self.scp_cmd + [local, full_remote]) | |
|
610 | 610 | |
|
611 | 611 | def send_files(self): |
|
612 | 612 | """send our files (called before start)""" |
@@ -268,7 +268,7 b" test_sections['qt'].requires('zmq', 'qt', 'pygments')" | |||
|
268 | 268 | |
|
269 | 269 | # html: |
|
270 | 270 | sec = test_sections['html'] |
|
271 | sec.requires('zmq', 'tornado', 'requests') | |
|
271 | sec.requires('zmq', 'tornado', 'requests', 'sqlite3') | |
|
272 | 272 | # The notebook 'static' directory contains JS, css and other |
|
273 | 273 | # files for web serving. Occasionally projects may put a .py |
|
274 | 274 | # file in there (MathJax ships a conf.py), so we might as |
@@ -19,8 +19,8 b' test suite.' | |||
|
19 | 19 | from __future__ import print_function |
|
20 | 20 | |
|
21 | 21 | import argparse |
|
22 | import json | |
|
22 | 23 | import multiprocessing.pool |
|
23 | from multiprocessing import Process, Queue | |
|
24 | 24 | import os |
|
25 | 25 | import shutil |
|
26 | 26 | import signal |
@@ -28,7 +28,7 b' import sys' | |||
|
28 | 28 | import subprocess |
|
29 | 29 | import time |
|
30 | 30 | |
|
31 | from .iptest import have, test_group_names as py_test_group_names, test_sections | |
|
31 | from .iptest import have, test_group_names as py_test_group_names, test_sections, StreamCapturer | |
|
32 | 32 | from IPython.utils.path import compress_user |
|
33 | 33 | from IPython.utils.py3compat import bytes_to_str |
|
34 | 34 | from IPython.utils.sysinfo import get_sys_info |
@@ -127,13 +127,14 b' class PyTestController(TestController):' | |||
|
127 | 127 | #: str, Python command to execute in subprocess |
|
128 | 128 | pycmd = None |
|
129 | 129 | |
|
130 | def __init__(self, section): | |
|
130 | def __init__(self, section, options): | |
|
131 | 131 | """Create new test runner.""" |
|
132 | 132 | TestController.__init__(self) |
|
133 | 133 | self.section = section |
|
134 | 134 | # pycmd is put into cmd[2] in PyTestController.launch() |
|
135 | 135 | self.cmd = [sys.executable, '-c', None, section] |
|
136 | 136 | self.pycmd = "from IPython.testing.iptest import run_iptest; run_iptest()" |
|
137 | self.options = options | |
|
137 | 138 | |
|
138 | 139 | def setup(self): |
|
139 | 140 | ipydir = TemporaryDirectory() |
@@ -145,6 +146,14 b' class PyTestController(TestController):' | |||
|
145 | 146 | # This means we won't get odd effects from our own matplotlib config |
|
146 | 147 | self.env['MPLCONFIGDIR'] = workingdir.name |
|
147 | 148 | |
|
149 | # From options: | |
|
150 | if self.options.xunit: | |
|
151 | self.add_xunit() | |
|
152 | if self.options.coverage: | |
|
153 | self.add_coverage() | |
|
154 | self.env['IPTEST_SUBPROC_STREAMS'] = self.options.subproc_streams | |
|
155 | self.cmd.extend(self.options.extra_args) | |
|
156 | ||
|
148 | 157 | @property |
|
149 | 158 | def will_run(self): |
|
150 | 159 | try: |
@@ -211,48 +220,77 b' class JSController(TestController):' | |||
|
211 | 220 | os.makedirs(os.path.join(self.nbdir.name, os.path.join(u'sub ∂ir2', u'sub ∂ir 1b'))) |
|
212 | 221 | |
|
213 | 222 | # start the ipython notebook, so we get the port number |
|
223 | self.server_port = 0 | |
|
214 | 224 | self._init_server() |
|
215 |
|
|
|
225 | if self.server_port: | |
|
226 | self.cmd.append("--port=%i" % self.server_port) | |
|
227 | else: | |
|
228 | # don't launch tests if the server didn't start | |
|
229 | self.cmd = [sys.executable, '-c', 'raise SystemExit(1)'] | |
|
216 | 230 | |
|
217 | 231 | def print_extra_info(self): |
|
218 | 232 | print("Running tests with notebook directory %r" % self.nbdir.name) |
|
219 | 233 | |
|
220 | 234 | @property |
|
221 | 235 | def will_run(self): |
|
222 | return all(have[a] for a in ['zmq', 'tornado', 'jinja2', 'casperjs']) | |
|
236 | return all(have[a] for a in ['zmq', 'tornado', 'jinja2', 'casperjs', 'sqlite3']) | |
|
223 | 237 | |
|
224 | 238 | def _init_server(self): |
|
225 | 239 | "Start the notebook server in a separate process" |
|
226 | self.queue = q = Queue() | |
|
227 | self.server = Process(target=run_webapp, args=(q, self.ipydir.name, self.nbdir.name)) | |
|
228 | self.server.start() | |
|
229 | self.server_port = q.get() | |
|
240 | self.server_command = command = [sys.executable, | |
|
241 | '-m', 'IPython.html', | |
|
242 | '--no-browser', | |
|
243 | '--ipython-dir', self.ipydir.name, | |
|
244 | '--notebook-dir', self.nbdir.name, | |
|
245 | ] | |
|
246 | # ipc doesn't work on Windows, and darwin has crazy-long temp paths, | |
|
247 | # which run afoul of ipc's maximum path length. | |
|
248 | if sys.platform.startswith('linux'): | |
|
249 | command.append('--KernelManager.transport=ipc') | |
|
250 | self.stream_capturer = c = StreamCapturer() | |
|
251 | c.start() | |
|
252 | self.server = subprocess.Popen(command, stdout=c.writefd, stderr=subprocess.STDOUT) | |
|
253 | self.server_info_file = os.path.join(self.ipydir.name, | |
|
254 | 'profile_default', 'security', 'nbserver-%i.json' % self.server.pid | |
|
255 | ) | |
|
256 | self._wait_for_server() | |
|
257 | ||
|
258 | def _wait_for_server(self): | |
|
259 | """Wait 30 seconds for the notebook server to start""" | |
|
260 | for i in range(300): | |
|
261 | if self.server.poll() is not None: | |
|
262 | return self._failed_to_start() | |
|
263 | if os.path.exists(self.server_info_file): | |
|
264 | self._load_server_info() | |
|
265 | return | |
|
266 | time.sleep(0.1) | |
|
267 | print("Notebook server-info file never arrived: %s" % self.server_info_file, | |
|
268 | file=sys.stderr | |
|
269 | ) | |
|
270 | ||
|
271 | def _failed_to_start(self): | |
|
272 | """Notebook server exited prematurely""" | |
|
273 | captured = self.stream_capturer.get_buffer().decode('utf-8', 'replace') | |
|
274 | print("Notebook failed to start: ", file=sys.stderr) | |
|
275 | print(self.server_command) | |
|
276 | print(captured, file=sys.stderr) | |
|
277 | ||
|
278 | def _load_server_info(self): | |
|
279 | """Notebook server started, load connection info from JSON""" | |
|
280 | with open(self.server_info_file) as f: | |
|
281 | info = json.load(f) | |
|
282 | self.server_port = info['port'] | |
|
230 | 283 | |
|
231 | 284 | def cleanup(self): |
|
285 | try: | |
|
232 | 286 | self.server.terminate() |
|
233 | self.server.join() | |
|
287 | except OSError: | |
|
288 | # already dead | |
|
289 | pass | |
|
290 | self.server.wait() | |
|
291 | self.stream_capturer.halt() | |
|
234 | 292 | TestController.cleanup(self) |
|
235 | 293 | |
|
236 | def run_webapp(q, ipydir, nbdir, loglevel=0): | |
|
237 | """start the IPython Notebook, and pass port back to the queue""" | |
|
238 | import os | |
|
239 | import IPython.html.notebookapp as nbapp | |
|
240 | import sys | |
|
241 | sys.stderr = open(os.devnull, 'w') | |
|
242 | server = nbapp.NotebookApp() | |
|
243 | args = ['--no-browser'] | |
|
244 | args.extend(['--ipython-dir', ipydir, | |
|
245 | '--notebook-dir', nbdir, | |
|
246 | '--log-level', str(loglevel), | |
|
247 | ]) | |
|
248 | # ipc doesn't work on Windows, and darwin has crazy-long temp paths, | |
|
249 | # which run afoul of ipc's maximum path length. | |
|
250 | if sys.platform.startswith('linux'): | |
|
251 | args.append('--KernelManager.transport=ipc') | |
|
252 | server.initialize(args) | |
|
253 | # communicate the port number to the parent process | |
|
254 | q.put(server.port) | |
|
255 | server.start() | |
|
256 | 294 | |
|
257 | 295 | def prepare_controllers(options): |
|
258 | 296 | """Returns two lists of TestController instances, those to run, and those |
@@ -273,28 +311,13 b' def prepare_controllers(options):' | |||
|
273 | 311 | test_sections['parallel'].enabled = False |
|
274 | 312 | |
|
275 | 313 | c_js = [JSController(name) for name in js_testgroups] |
|
276 | c_py = [PyTestController(name) for name in py_testgroups] | |
|
277 | ||
|
278 | configure_py_controllers(c_py, xunit=options.xunit, | |
|
279 | coverage=options.coverage, subproc_streams=options.subproc_streams, | |
|
280 | extra_args=options.extra_args) | |
|
314 | c_py = [PyTestController(name, options) for name in py_testgroups] | |
|
281 | 315 | |
|
282 | 316 | controllers = c_py + c_js |
|
283 | 317 | to_run = [c for c in controllers if c.will_run] |
|
284 | 318 | not_run = [c for c in controllers if not c.will_run] |
|
285 | 319 | return to_run, not_run |
|
286 | 320 | |
|
287 | def configure_py_controllers(controllers, xunit=False, coverage=False, | |
|
288 | subproc_streams='capture', extra_args=()): | |
|
289 | """Apply options for a collection of TestController objects.""" | |
|
290 | for controller in controllers: | |
|
291 | if xunit: | |
|
292 | controller.add_xunit() | |
|
293 | if coverage: | |
|
294 | controller.add_coverage() | |
|
295 | controller.env['IPTEST_SUBPROC_STREAMS'] = subproc_streams | |
|
296 | controller.cmd.extend(extra_args) | |
|
297 | ||
|
298 | 321 | def do_run(controller, buffer_output=True): |
|
299 | 322 | """Setup and run a test controller. |
|
300 | 323 |
@@ -26,19 +26,6 b' files for each profile, and the files look like :file:`ipython_config.py` or' | |||
|
26 | 26 | which defaults to :file:`$HOME/.ipython`. For Windows users, :envvar:`HOME` |
|
27 | 27 | resolves to :file:`C:\\Users\\{YourUserName}` in most instances. |
|
28 | 28 | |
|
29 | ||
|
30 | Eventloop integration | |
|
31 | --------------------- | |
|
32 | ||
|
33 | Previously IPython had command line options for controlling GUI event loop | |
|
34 | integration (-gthread, -qthread, -q4thread, -wthread, -pylab). As of IPython | |
|
35 | version 0.11, these have been removed. Please see the new ``%gui`` | |
|
36 | magic command or :ref:`this section <gui_support>` for details on the new | |
|
37 | interface, or specify the gui at the commandline:: | |
|
38 | ||
|
39 | $ ipython --gui=qt | |
|
40 | ||
|
41 | ||
|
42 | 29 | Command-line Options |
|
43 | 30 | -------------------- |
|
44 | 31 | |
@@ -131,11 +118,9 b' Note that cell magics *always* require an explicit ``%%`` prefix, automagic' | |||
|
131 | 118 | calling only works for line magics. |
|
132 | 119 | |
|
133 | 120 | The automagic system has the lowest possible precedence in name searches, so |
|
134 | defining an identifier with the same name as an existing magic function will | |
|
135 | shadow it for automagic use. You can still access the shadowed magic function | |
|
136 | by explicitly using the ``%`` character at the beginning of the line. | |
|
137 | ||
|
138 | An example (with automagic on) should clarify all this: | |
|
121 | you can freely use variables with the same names as magic commands. If a magic | |
|
122 | command is 'shadowed' by a variable, you will need the explicit ``%`` prefix to | |
|
123 | use it: | |
|
139 | 124 | |
|
140 | 125 | .. sourcecode:: ipython |
|
141 | 126 | |
@@ -378,25 +363,16 b' Search command history' | |||
|
378 | 363 | IPython provides two ways for searching through previous input and thus |
|
379 | 364 | reduce the need for repetitive typing: |
|
380 | 365 | |
|
381 | 1. Start typing, and then use Ctrl-p (previous,up) and Ctrl-n | |
|
382 |
|
|
|
383 |
what you've typed so far. |
|
|
384 | prompt, they just behave like normal arrow keys. | |
|
385 | 2. Hit Ctrl-r: opens a search prompt. Begin typing and the system | |
|
366 | 1. Start typing, and then use the up and down arrow keys (or :kbd:`Ctrl-p` | |
|
367 | and :kbd:`Ctrl-n`) to search through only the history items that match | |
|
368 | what you've typed so far. | |
|
369 | 2. Hit :kbd:`Ctrl-r`: to open a search prompt. Begin typing and the system | |
|
386 | 370 | searches your history for lines that contain what you've typed so |
|
387 | 371 | far, completing as much as it can. |
|
388 | 372 | |
|
389 | ||
|
390 | Persistent command history across sessions | |
|
391 | ++++++++++++++++++++++++++++++++++++++++++ | |
|
392 | ||
|
393 | 373 | IPython will save your input history when it leaves and reload it next |
|
394 | 374 | time you restart it. By default, the history file is named |
|
395 | $IPYTHONDIR/profile_<name>/history.sqlite. This allows you to keep | |
|
396 | separate histories related to various tasks: commands related to | |
|
397 | numerical work will not be clobbered by a system shell history, for | |
|
398 | example. | |
|
399 | ||
|
375 | :file:`.ipython/profile_{name}/history.sqlite`. | |
|
400 | 376 | |
|
401 | 377 | Autoindent |
|
402 | 378 | ++++++++++ |
@@ -405,7 +381,7 b" IPython can recognize lines ending in ':' and indent the next line," | |||
|
405 | 381 | while also un-indenting automatically after 'raise' or 'return'. |
|
406 | 382 | |
|
407 | 383 | This feature uses the readline library, so it will honor your |
|
408 | :file:`~/.inputrc` configuration (or whatever file your INPUTRC variable points | |
|
384 | :file:`~/.inputrc` configuration (or whatever file your :envvar:`INPUTRC` environment variable points | |
|
409 | 385 | to). Adding the following lines to your :file:`.inputrc` file can make |
|
410 | 386 | indenting/unindenting more convenient (M-i indents, M-u unindents):: |
|
411 | 387 | |
@@ -441,20 +417,15 b' Customizing readline behavior' | |||
|
441 | 417 | |
|
442 | 418 | All these features are based on the GNU readline library, which has an |
|
443 | 419 | extremely customizable interface. Normally, readline is configured via a |
|
444 | file which defines the behavior of the library; the details of the | |
|
445 | syntax for this can be found in the readline documentation available | |
|
446 | with your system or on the Internet. IPython doesn't read this file (if | |
|
447 | it exists) directly, but it does support passing to readline valid | |
|
448 | options via a simple interface. In brief, you can customize readline by | |
|
449 | setting the following options in your configuration file (note | |
|
450 | that these options can not be specified at the command line): | |
|
451 | ||
|
452 | * **readline_parse_and_bind**: this holds a list of strings to be executed | |
|
420 | :file:`.inputrc` file. IPython respects this, and you can also customise readline | |
|
421 | by setting the following :doc:`configuration </config/intro>` options: | |
|
422 | ||
|
423 | * ``InteractiveShell.readline_parse_and_bind``: this holds a list of strings to be executed | |
|
453 | 424 | via a readline.parse_and_bind() command. The syntax for valid commands |
|
454 | 425 | of this kind can be found by reading the documentation for the GNU |
|
455 | 426 | readline library, as these commands are of the kind which readline |
|
456 | 427 | accepts in its configuration file. |
|
457 |
* |
|
|
428 | * ``InteractiveShell.readline_remove_delims``: a string of characters to be removed | |
|
458 | 429 | from the default word-delimiters list used by readline, so that |
|
459 | 430 | completions may be performed on strings which contain them. Do not |
|
460 | 431 | change the default value unless you know what you're doing. |
@@ -595,7 +566,7 b' detailed tracebacks. Furthermore, both normal and verbose tracebacks can' | |||
|
595 | 566 | be colored (if your terminal supports it) which makes them much easier |
|
596 | 567 | to parse visually. |
|
597 | 568 | |
|
598 |
See the magic xmode and colors functions for details |
|
|
569 | See the magic xmode and colors functions for details. | |
|
599 | 570 | |
|
600 | 571 | These features are basically a terminal version of Ka-Ping Yee's cgitb |
|
601 | 572 | module, now part of the standard Python library. |
@@ -612,7 +583,7 b' retrieved as variables (besides the usual arrow key recall), in' | |||
|
612 | 583 | addition to the %rep magic command that brings a history entry |
|
613 | 584 | up for editing on the next command line. |
|
614 | 585 | |
|
615 |
The following |
|
|
586 | The following variables always exist: | |
|
616 | 587 | |
|
617 | 588 | * _i, _ii, _iii: store previous, next previous and next-next previous inputs. |
|
618 | 589 | * In, _ih : a list of all inputs; _ih[n] is the input from line n. If you |
@@ -622,14 +593,13 b" The following GLOBAL variables always exist (so don't overwrite them!):" | |||
|
622 | 593 | Additionally, global variables named _i<n> are dynamically created (<n> |
|
623 | 594 | being the prompt counter), so ``_i<n> == _ih[<n>] == In[<n>]``. |
|
624 | 595 | |
|
625 | For example, what you typed at prompt 14 is available as _i14, _ih[14] | |
|
626 | and In[14]. | |
|
596 | For example, what you typed at prompt 14 is available as ``_i14``, ``_ih[14]`` | |
|
597 | and ``In[14]``. | |
|
627 | 598 | |
|
628 | 599 | This allows you to easily cut and paste multi line interactive prompts |
|
629 | 600 | by printing them out: they print like a clean string, without prompt |
|
630 | 601 | characters. You can also manipulate them like regular variables (they |
|
631 |
are strings), modify or exec them |
|
|
632 | contents of input prompt 9. | |
|
602 | are strings), modify or exec them. | |
|
633 | 603 | |
|
634 | 604 | You can also re-execute multiple lines of input easily by using the |
|
635 | 605 | magic %rerun or %macro functions. The macro system also allows you to re-execute |
@@ -655,7 +625,7 b' result (NOT assignments, for example) are cached. If you are familiar' | |||
|
655 | 625 | with Mathematica, IPython's _ variables behave exactly like |
|
656 | 626 | Mathematica's % variables. |
|
657 | 627 | |
|
658 |
The following |
|
|
628 | The following variables always exist: | |
|
659 | 629 | |
|
660 | 630 |
* [_] (a single underscore) |
|
661 | 631 | default interpreter. |
@@ -665,22 +635,21 b" The following GLOBAL variables always exist (so don't overwrite them!):" | |||
|
665 | 635 | Additionally, global variables named _<n> are dynamically created (<n> |
|
666 | 636 | being the prompt counter), such that the result of output <n> is always |
|
667 | 637 | available as _<n> (don't use the angle brackets, just the number, e.g. |
|
668 | _21). | |
|
638 | ``_21``). | |
|
669 | 639 | |
|
670 | 640 | These variables are also stored in a global dictionary (not a |
|
671 | 641 | list, since it only has entries for lines which returned a result) |
|
672 | 642 | available under the names _oh and Out (similar to _ih and In). So the |
|
673 | output from line 12 can be obtained as _12, Out[12] or _oh[12]. If you | |
|
643 | output from line 12 can be obtained as ``_12``, ``Out[12]`` or ``_oh[12]``. If you | |
|
674 | 644 | accidentally overwrite the Out variable you can recover it by typing |
|
675 |
|
|
|
645 | ``Out=_oh`` at the prompt. | |
|
676 | 646 | |
|
677 | 647 | This system obviously can potentially put heavy memory demands on your |
|
678 | 648 | system, since it prevents Python's garbage collector from removing any |
|
679 | 649 | previously computed results. You can control how many results are kept |
|
680 | in memory with the option (at the command line or in your configuration | |
|
681 | file) cache_size. If you set it to 0, the whole system is completely | |
|
682 | disabled and the prompts revert to the classic '>>>' of normal Python. | |
|
683 | ||
|
650 | in memory with the configuration option ``InteractiveShell.cache_size``. | |
|
651 | If you set it to 0, output caching is disabled. You can also use the ``%reset`` | |
|
652 | and ``%xdel`` magics to clear large items from memory. | |
|
684 | 653 | |
|
685 | 654 | Directory history |
|
686 | 655 | ----------------- |
@@ -697,16 +666,17 b' Automatic parentheses and quotes' | |||
|
697 | 666 | These features were adapted from Nathan Gray's LazyPython. They are |
|
698 | 667 | meant to allow less typing for common situations. |
|
699 | 668 | |
|
700 | ||
|
701 | Automatic parentheses | |
|
702 | +++++++++++++++++++++ | |
|
703 | ||
|
704 | 669 | Callable objects (i.e. functions, methods, etc) can be invoked like this |
|
705 | 670 | (notice the commas between the arguments):: |
|
706 | 671 | |
|
707 | 672 | In [1]: callable_ob arg1, arg2, arg3 |
|
708 | 673 | ------> callable_ob(arg1, arg2, arg3) |
|
709 | 674 | |
|
675 | .. note:: | |
|
676 | This feature is disabled by default. To enable it, use the ``%autocall`` | |
|
677 | magic command. The commands below with special prefixes will always work, | |
|
678 | however. | |
|
679 | ||
|
710 | 680 | You can force automatic parentheses by using '/' as the first character |
|
711 | 681 | of a line. For example:: |
|
712 | 682 | |
@@ -730,17 +700,10 b' but this will work::' | |||
|
730 | 700 | Out[5]: [(1, 4), (2, 5), (3, 6)] |
|
731 | 701 | |
|
732 | 702 | IPython tells you that it has altered your command line by displaying |
|
733 |
the new command line preceded by ->. |
|
|
734 | ||
|
735 | In [6]: callable list | |
|
736 | ------> callable(list) | |
|
703 | the new command line preceded by ``--->``. | |
|
737 | 704 | |
|
738 | ||
|
739 | Automatic quoting | |
|
740 | +++++++++++++++++ | |
|
741 | ||
|
742 | You can force automatic quoting of a function's arguments by using ',' | |
|
743 | or ';' as the first character of a line. For example:: | |
|
705 | You can force automatic quoting of a function's arguments by using ``,`` | |
|
706 | or ``;`` as the first character of a line. For example:: | |
|
744 | 707 | |
|
745 | 708 | In [1]: ,my_function /home/me # becomes my_function("/home/me") |
|
746 | 709 | |
@@ -770,7 +733,7 b' environment anytime you start Python::' | |||
|
770 | 733 | raise SystemExit |
|
771 | 734 | |
|
772 | 735 | The ``raise SystemExit`` is needed to exit Python when |
|
773 |
it finishes, otherwise you'll be back at the normal Python |
|
|
736 | it finishes, otherwise you'll be back at the normal Python ``>>>`` | |
|
774 | 737 | prompt. |
|
775 | 738 | |
|
776 | 739 | This is probably useful to developers who manage multiple Python |
@@ -788,12 +751,12 b' You can start a regular IPython session with' | |||
|
788 | 751 | .. sourcecode:: python |
|
789 | 752 | |
|
790 | 753 | import IPython |
|
791 | IPython.start_ipython() | |
|
754 | IPython.start_ipython(argv=[]) | |
|
792 | 755 | |
|
793 | 756 | at any point in your program. This will load IPython configuration, |
|
794 | 757 | startup files, and everything, just as if it were a normal IPython session. |
|
795 | In addition to this, | |
|
796 |
|
|
|
758 | ||
|
759 | It is also possible to embed an IPython shell in a namespace in your Python code. | |
|
797 | 760 | This allows you to evaluate dynamically the state of your code, |
|
798 | 761 | operate with your variables, analyze them, etc. Note however that |
|
799 | 762 | any changes you make to values while in the shell do not propagate back |
@@ -826,13 +789,10 b' your Python programs for this to work (detailed examples follow later)::' | |||
|
826 | 789 | |
|
827 | 790 | embed() # this call anywhere in your program will start IPython |
|
828 | 791 | |
|
829 | .. note:: | |
|
830 | ||
|
831 | As of 0.13, you can embed an IPython *kernel*, for use with qtconsole, | |
|
832 | etc. via ``IPython.embed_kernel()`` instead of ``IPython.embed()``. | |
|
833 | It should function just the same as regular embed, but you connect | |
|
834 | an external frontend rather than IPython starting up in the local | |
|
835 | terminal. | |
|
792 | You can also embed an IPython *kernel*, for use with qtconsole, etc. via | |
|
793 | ``IPython.embed_kernel()``. This should function work the same way, but you can | |
|
794 | connect an external frontend (``ipython qtconsole`` or ``ipython console``), | |
|
795 | rather than interacting with it in the terminal. | |
|
836 | 796 | |
|
837 | 797 | You can run embedded instances even in code which is itself being run at |
|
838 | 798 | the IPython interactive prompt with '%run <filename>'. Since it's easy |
@@ -872,45 +832,31 b' pdb, the Python debugger, is a powerful interactive debugger which' | |||
|
872 | 832 | allows you to step through code, set breakpoints, watch variables, |
|
873 | 833 | etc. IPython makes it very easy to start any script under the control |
|
874 | 834 | of pdb, regardless of whether you have wrapped it into a 'main()' |
|
875 |
function or not. For this, simply type |
|
|
876 |
IPython prompt. See the %run command's documentation |
|
|
877 | in Sec. magic_ for more details, including how to control where pdb | |
|
878 | will stop execution first. | |
|
879 | ||
|
880 | For more information on the use of the pdb debugger, read the included | |
|
881 | pdb.doc file (part of the standard Python distribution). On a stock | |
|
882 | Linux system it is located at /usr/lib/python2.3/pdb.doc, but the | |
|
883 | easiest way to read it is by using the help() function of the pdb module | |
|
884 | as follows (in an IPython prompt):: | |
|
835 | function or not. For this, simply type ``%run -d myscript`` at an | |
|
836 | IPython prompt. See the %run command's documentation for more details, including | |
|
837 | how to control where pdb will stop execution first. | |
|
885 | 838 | |
|
886 | In [1]: import pdb | |
|
887 | In [2]: pdb.help() | |
|
839 | For more information on the use of the pdb debugger, see :ref:`debugger-commands` | |
|
840 | in the Python documentation. | |
|
888 | 841 | |
|
889 | This will load the pdb.doc document in a file viewer for you automatically. | |
|
890 | 842 | |
|
843 | Post-mortem debugging | |
|
844 | --------------------- | |
|
891 | 845 | |
|
892 | Automatic invocation of pdb on exceptions | |
|
893 | ----------------------------------------- | |
|
894 | ||
|
895 | IPython, if started with the ``--pdb`` option (or if the option is set in | |
|
896 | your config file) can call the Python pdb debugger every time your code | |
|
897 | triggers an uncaught exception. This feature | |
|
898 | can also be toggled at any time with the %pdb magic command. This can be | |
|
846 | Going into a debugger when an exception occurs can be | |
|
899 | 847 | extremely useful in order to find the origin of subtle bugs, because pdb |
|
900 | 848 | opens up at the point in your code which triggered the exception, and |
|
901 | 849 | while your program is at this point 'dead', all the data is still |
|
902 | 850 | available and you can walk up and down the stack frame and understand |
|
903 | 851 | the origin of the problem. |
|
904 | 852 | |
|
905 | Furthermore, you can use these debugging facilities both with the | |
|
906 | embedded IPython mode and without IPython at all. For an embedded shell | |
|
907 | (see sec. Embedding_), simply call the constructor with | |
|
908 | ``--pdb`` in the argument string and pdb will automatically be called if an | |
|
909 | uncaught exception is triggered by your code. | |
|
853 | You can use the ``%debug`` magic after an exception has occurred to start | |
|
854 | post-mortem debugging. IPython can also call debugger every time your code | |
|
855 | triggers an uncaught exception. This feature can be toggled with the %pdb magic | |
|
856 | command, or you can start IPython with the ``--pdb`` option. | |
|
910 | 857 | |
|
911 | For stand-alone use of the feature in your programs which do not use | |
|
912 |
|
|
|
913 | routine:: | |
|
858 | For a post-mortem debugger in your programs outside IPython, | |
|
859 | put the following lines toward the top of your 'main' routine:: | |
|
914 | 860 | |
|
915 | 861 | import sys |
|
916 | 862 | from IPython.core import ultratb |
@@ -925,25 +871,10 b' options which can be set in IPython with ``--colors`` and ``--xmode``.' | |||
|
925 | 871 | This will give any of your programs detailed, colored tracebacks with |
|
926 | 872 | automatic invocation of pdb. |
|
927 | 873 | |
|
928 | ||
|
929 | Extensions for syntax processing | |
|
930 | ================================ | |
|
931 | ||
|
932 | This isn't for the faint of heart, because the potential for breaking | |
|
933 | things is quite high. But it can be a very powerful and useful feature. | |
|
934 | In a nutshell, you can redefine the way IPython processes the user input | |
|
935 | line to accept new, special extensions to the syntax without needing to | |
|
936 | change any of IPython's own code. | |
|
937 | ||
|
938 | In the IPython/extensions directory you will find some examples | |
|
939 | supplied, which we will briefly describe now. These can be used 'as is' | |
|
940 | (and both provide very useful functionality), or you can use them as a | |
|
941 | starting point for writing your own extensions. | |
|
942 | ||
|
943 | 874 | .. _pasting_with_prompts: |
|
944 | 875 | |
|
945 | 876 | Pasting of code starting with Python or IPython prompts |
|
946 | ------------------------------------------------------- | |
|
877 | ======================================================= | |
|
947 | 878 | |
|
948 | 879 | IPython is smart enough to filter out input prompts, be they plain Python ones |
|
949 | 880 | (``>>>`` and ``...``) or IPython ones (``In [N]:`` and ``...:``). You can |
@@ -1012,6 +943,11 b' object, do::' | |||
|
1012 | 943 | |
|
1013 | 944 | %gui wx |
|
1014 | 945 | |
|
946 | You can also start IPython with an event loop set up using the :option:`--gui` | |
|
947 | flag:: | |
|
948 | ||
|
949 | $ ipython --gui=qt | |
|
950 | ||
|
1015 | 951 | For information on IPython's matplotlib_ integration (and the ``matplotlib`` |
|
1016 | 952 | mode) see :ref:`this section <matplotlib_support>`. |
|
1017 | 953 | |
@@ -1135,29 +1071,23 b' demo::' | |||
|
1135 | 1071 | mydemo = Demo('myscript.py') |
|
1136 | 1072 | |
|
1137 | 1073 | This creates the mydemo object, whose blocks you run one at a time by |
|
1138 |
simply calling the object with no arguments. |
|
|
1139 | in IPython (the default), all you need to do is type:: | |
|
1074 | simply calling the object with no arguments. Then call it to run each step | |
|
1075 | of the demo:: | |
|
1140 | 1076 | |
|
1141 |
mydemo |
|
|
1077 | mydemo() | |
|
1142 | 1078 | |
|
1143 | and IPython will call it, executing each block. Demo objects can be | |
|
1079 | Demo objects can be | |
|
1144 | 1080 | restarted, you can move forward or back skipping blocks, re-execute the |
|
1145 | last block, etc. Simply use the Tab key on a demo object to see its | |
|
1146 | methods, and call '?' on them to see their docstrings for more usage | |
|
1147 | details. In addition, the demo module itself contains a comprehensive | |
|
1148 | docstring, which you can access via:: | |
|
1149 | ||
|
1150 | from IPython.lib import demo | |
|
1151 | ||
|
1152 | demo? | |
|
1081 | last block, etc. See the :mod:`IPython.lib.demo` module and the | |
|
1082 | :class:`~IPython.lib.demo.Demo` class for details. | |
|
1153 | 1083 | |
|
1154 |
Limitations: |
|
|
1084 | Limitations: These demos are limited to | |
|
1155 | 1085 | fairly simple uses. In particular, you cannot break up sections within |
|
1156 | 1086 | indented code (loops, if statements, function definitions, etc.) |
|
1157 | 1087 | Supporting something like this would basically require tracking the |
|
1158 | 1088 | internal execution state of the Python interpreter, so only top-level |
|
1159 | 1089 | divisions are allowed. If you want to be able to open an IPython |
|
1160 | 1090 | instance at an arbitrary point in a program, you can use IPython's |
|
1161 | embedding facilities, see :func:`IPython.embed` for details. | |
|
1091 | :ref:`embedding facilities <Embedding>`. | |
|
1162 | 1092 | |
|
1163 | 1093 | .. include:: ../links.txt |
@@ -1,5 +1,4 b'' | |||
|
1 | 1 | #!/usr/bin/env python |
|
2 | ||
|
3 | 2 | """An example of how to embed an IPython shell into a running program. |
|
4 | 3 | |
|
5 | 4 | Please see the documentation in the IPython.Shell module for more details. |
@@ -13,7 +12,7 b' from __future__ import print_function' | |||
|
13 | 12 | |
|
14 | 13 | # The basics to get you going: |
|
15 | 14 | |
|
16 |
# IPython |
|
|
15 | # IPython injects get_ipython into builtins, so you can know if you have nested | |
|
17 | 16 | # copies running. |
|
18 | 17 | |
|
19 | 18 | # Try running this code both at the command line and from inside IPython (with |
@@ -16,7 +16,6 b" print('unless auto_all has been set to true in the demo object')" | |||
|
16 | 16 | |
|
17 | 17 | # The mark below defines a block boundary, which is a point where IPython will |
|
18 | 18 | # stop execution and return to the interactive prompt. |
|
19 | # Note that in actual interactive execution, | |
|
20 | 19 | # <demo> --- stop --- |
|
21 | 20 | |
|
22 | 21 | x = 1 |
General Comments 0
You need to be logged in to leave comments.
Login now