Show More
@@ -0,0 +1,73 b'' | |||
|
1 | """ Debug a script (like %run -d) in IPython process, Using WinPdb | |
|
2 | ||
|
3 | Usage: | |
|
4 | ||
|
5 | %wdb test.py | |
|
6 | run test.py, with a winpdb breakpoint at start of the file | |
|
7 | ||
|
8 | %wdb pass | |
|
9 | Change the password (e.g. if you have forgotten the old one) | |
|
10 | """ | |
|
11 | ||
|
12 | import os | |
|
13 | ||
|
14 | import IPython.ipapi | |
|
15 | import rpdb2 | |
|
16 | ||
|
17 | ip = IPython.ipapi.get() | |
|
18 | ||
|
19 | rpdb_started = False | |
|
20 | ||
|
21 | def wdb_f(self, arg): | |
|
22 | """ Debug a script (like %run -d) in IPython process, Using WinPdb | |
|
23 | ||
|
24 | Usage: | |
|
25 | ||
|
26 | %wdb test.py | |
|
27 | run test.py, with a winpdb breakpoint at start of the file | |
|
28 | ||
|
29 | %wdb pass | |
|
30 | Change the password (e.g. if you have forgotten the old one) | |
|
31 | ||
|
32 | Note that after the script has been run, you need to do "Go" (f5) | |
|
33 | in WinPdb to resume normal IPython operation. | |
|
34 | """ | |
|
35 | ||
|
36 | global rpdb_started | |
|
37 | if not arg.strip(): | |
|
38 | print __doc__ | |
|
39 | return | |
|
40 | ||
|
41 | if arg.strip() == 'pass': | |
|
42 | passwd = raw_input('Enter new winpdb session password: ') | |
|
43 | ip.db['winpdb_pass'] = passwd | |
|
44 | print "Winpdb password changed" | |
|
45 | if rpdb_started: | |
|
46 | print "You need to restart IPython to use the new password" | |
|
47 | return | |
|
48 | ||
|
49 | path = os.path.abspath(arg) | |
|
50 | if not os.path.isfile(path): | |
|
51 | raise IPython.ipapi.UsageError("%%wdb: file %s does not exist" % path) | |
|
52 | if not rpdb_started: | |
|
53 | passwd = ip.db.get('winpdb_pass', None) | |
|
54 | if passwd is None: | |
|
55 | import textwrap | |
|
56 | print textwrap.dedent("""\ | |
|
57 | Winpdb sessions need a password that you use for attaching the external | |
|
58 | winpdb session. IPython will remember this. You can change the password later | |
|
59 | by '%wpdb pass' | |
|
60 | """) | |
|
61 | passwd = raw_input('Enter new winpdb session password: ') | |
|
62 | ip.db['winpdb_pass'] = passwd | |
|
63 | ||
|
64 | print "Starting rpdb2 in IPython process" | |
|
65 | rpdb2.start_embedded_debugger(passwd, timeout = 0) | |
|
66 | rpdb_started = True | |
|
67 | ||
|
68 | rpdb2.set_temp_breakpoint(path) | |
|
69 | print 'It is time to attach with WinPdb (launch WinPdb if needed, File -> Attach)' | |
|
70 | ip.magic('%run ' + arg) | |
|
71 | ||
|
72 | ||
|
73 | ip.expose_magic('wdb', wdb_f) |
@@ -87,6 +87,8 b' def main():' | |||
|
87 | 87 | # For bzr completer, requires bzrlib (the python installation of bzr) |
|
88 | 88 | #import ipy_bzr |
|
89 | 89 | |
|
90 | ||
|
91 | ||
|
90 | 92 | # some config helper functions you can use |
|
91 | 93 | def import_all(modules): |
|
92 | 94 | """ Usage: import_all("os sys") """ |
@@ -92,7 +92,7 b' class NonBlockingIPShell(object):' | |||
|
92 | 92 | |
|
93 | 93 | def __init__(self,argv=[],user_ns={},user_global_ns=None, |
|
94 | 94 | cin=None, cout=None, cerr=None, |
|
95 | ask_exit_handler=None): | |
|
95 | ask_exit_handler=None, rawinput=None): | |
|
96 | 96 | ''' |
|
97 | 97 | @param argv: Command line options for IPython |
|
98 | 98 | @type argv: list |
@@ -114,7 +114,7 b' class NonBlockingIPShell(object):' | |||
|
114 | 114 | #ipython0 initialisation |
|
115 | 115 | self.initIpython0(argv, user_ns, user_global_ns, |
|
116 | 116 | cin, cout, cerr, |
|
117 | ask_exit_handler) | |
|
117 | ask_exit_handler, rawinput) | |
|
118 | 118 | |
|
119 | 119 | #vars used by _execute |
|
120 | 120 | self._iter_more = 0 |
@@ -133,7 +133,7 b' class NonBlockingIPShell(object):' | |||
|
133 | 133 | |
|
134 | 134 | def initIpython0(self, argv=[], user_ns={}, user_global_ns=None, |
|
135 | 135 | cin=None, cout=None, cerr=None, |
|
136 | ask_exit_handler=None): | |
|
136 | ask_exit_handler=None, rawinput=None): | |
|
137 | 137 | #first we redefine in/out/error functions of IPython |
|
138 | 138 | if cin: |
|
139 | 139 | IPython.Shell.Term.cin = cin |
@@ -167,7 +167,8 b' class NonBlockingIPShell(object):' | |||
|
167 | 167 | self._IP.set_hook('shell_hook',self._shell) |
|
168 | 168 | |
|
169 | 169 | #we replace the ipython default input command caller by our method |
|
170 |
IPython.iplib.raw_input_original = |
|
|
170 | IPython.iplib.raw_input_original = rawinput | |
|
171 | ||
|
171 | 172 | #we replace the ipython default exit command by our method |
|
172 | 173 | self._IP.exit = ask_exit_handler |
|
173 | 174 | #we replace the help command |
@@ -339,12 +340,6 b' class NonBlockingIPShell(object):' | |||
|
339 | 340 | ''' |
|
340 | 341 | pass |
|
341 | 342 | |
|
342 | #def _askExit(self): | |
|
343 | # ''' | |
|
344 | # Can be redefined to generate post event to exit the Ipython shell | |
|
345 | # ''' | |
|
346 | # pass | |
|
347 | ||
|
348 | 343 | def _getHistoryMaxIndex(self): |
|
349 | 344 | ''' |
|
350 | 345 | returns the max length of the history buffer |
@@ -385,18 +380,6 b' class NonBlockingIPShell(object):' | |||
|
385 | 380 | ''' |
|
386 | 381 | self._doc_text = text |
|
387 | 382 | |
|
388 | def _raw_input(self, prompt=''): | |
|
389 | ''' | |
|
390 | Custom raw_input() replacement. Get's current line from console buffer. | |
|
391 | ||
|
392 | @param prompt: Prompt to print. Here for compatability as replacement. | |
|
393 | @type prompt: string | |
|
394 | ||
|
395 | @return: The current command line text. | |
|
396 | @rtype: string | |
|
397 | ''' | |
|
398 | return self._line_to_execute | |
|
399 | ||
|
400 | 383 | def _execute(self): |
|
401 | 384 | ''' |
|
402 | 385 | Executes the current line provided by the shell object. |
@@ -47,11 +47,12 b' class WxNonBlockingIPShell(NonBlockingIPShell):' | |||
|
47 | 47 | def __init__(self, parent, |
|
48 | 48 | argv=[],user_ns={},user_global_ns=None, |
|
49 | 49 | cin=None, cout=None, cerr=None, |
|
50 | ask_exit_handler=None): | |
|
50 | ask_exit_handler=None, rawinput=None): | |
|
51 | 51 | |
|
52 | 52 | NonBlockingIPShell.__init__(self,argv,user_ns,user_global_ns, |
|
53 | 53 | cin, cout, cerr, |
|
54 |
ask_exit_handler |
|
|
54 | ask_exit_handler, | |
|
55 | rawinput) | |
|
55 | 56 | |
|
56 | 57 | self.parent = parent |
|
57 | 58 | |
@@ -302,18 +303,6 b' class WxConsoleView(stc.StyledTextCtrl):' | |||
|
302 | 303 | return self.GetTextRange(self.getCurrentPromptStart(), |
|
303 | 304 | self.getCurrentLineEnd()) |
|
304 | 305 | |
|
305 | def showReturned(self, text): | |
|
306 | ''' | |
|
307 | Show returned text from last command and print new prompt. | |
|
308 | ||
|
309 | @param text: Text to show. | |
|
310 | @type text: string | |
|
311 | ''' | |
|
312 | self.write('\n'+text) | |
|
313 | if text: | |
|
314 | self.write('\n') | |
|
315 | self.showPrompt() | |
|
316 | ||
|
317 | 306 | def moveCursorOnNewValidKey(self): |
|
318 | 307 | #If cursor is at wrong position put it at last line... |
|
319 | 308 | if self.GetCurrentPos() < self.getCurrentPromptStart(): |
@@ -406,7 +395,7 b' class WxConsoleView(stc.StyledTextCtrl):' | |||
|
406 | 395 | elif event.GetKeyCode() == wx.WXK_BACK: |
|
407 | 396 | self.moveCursorOnNewValidKey() |
|
408 | 397 | if self.getCursorPos() > self.getCurrentPromptStart(): |
|
409 | self.removeFromTo(self.getCursorPos()-1,self.getCursorPos()) | |
|
398 | event.Skip() | |
|
410 | 399 | return True |
|
411 | 400 | |
|
412 | 401 | if skip: |
@@ -461,6 +450,7 b' class IPShellWidget(wx.Panel):' | |||
|
461 | 450 | because it seems to be more useful |
|
462 | 451 | Any idea to make it more 'generic' welcomed. |
|
463 | 452 | ''' |
|
453 | ||
|
464 | 454 | def __init__(self, parent, intro=None, |
|
465 | 455 | background_color="BLACK", add_button_handler=None, |
|
466 | 456 | wx_ip_shell=None, |
@@ -475,15 +465,15 b' class IPShellWidget(wx.Panel):' | |||
|
475 | 465 | |
|
476 | 466 | ### IPython non blocking shell instanciation ### |
|
477 | 467 | self.cout = StringIO() |
|
478 | ||
|
479 | 468 | self.add_button_handler = add_button_handler |
|
480 | 469 | |
|
481 | 470 | if wx_ip_shell is not None: |
|
482 | 471 | self.IP = wx_ip_shell |
|
483 | 472 | else: |
|
484 | 473 | self.IP = WxNonBlockingIPShell(self, |
|
485 | cout = self.cout,cerr = self.cout, | |
|
486 |
ask_exit_handler = self.askExitCallback |
|
|
474 | cout = self.cout, cerr = self.cout, | |
|
475 | ask_exit_handler = self.askExitCallback, | |
|
476 | rawinput = self.rawInput) | |
|
487 | 477 | |
|
488 | 478 | ### IPython wx console view instanciation ### |
|
489 | 479 | #If user didn't defined an intro text, we create one for him |
@@ -501,9 +491,11 b' class IPShellWidget(wx.Panel):' | |||
|
501 | 491 | self.IP.getPrompt(), |
|
502 | 492 | intro=welcome_text, |
|
503 | 493 | background_color=background_color) |
|
494 | ||
|
495 | self.cout.write = self.text_ctrl.write | |
|
504 | 496 | |
|
505 | 497 | self.text_ctrl.Bind(wx.EVT_KEY_DOWN, self.keyPress, self.text_ctrl) |
|
506 | ||
|
498 | ||
|
507 | 499 | ### making the layout of the panel ### |
|
508 | 500 | sizer = wx.BoxSizer(wx.VERTICAL) |
|
509 | 501 | sizer.Add(self.text_ctrl, 1, wx.EXPAND) |
@@ -525,6 +517,7 b' class IPShellWidget(wx.Panel):' | |||
|
525 | 517 | def stateDoExecuteLine(self): |
|
526 | 518 | #print >>sys.__stdout__,"command:",self.getCurrentLine() |
|
527 | 519 | line=self.text_ctrl.getCurrentLine() |
|
520 | self.text_ctrl.write('\n') | |
|
528 | 521 | self.IP.doExecute((line.replace('\t',' '*4)).encode('cp1252')) |
|
529 | 522 | self.updateHistoryTracker(self.text_ctrl.getCurrentLine()) |
|
530 | 523 | self.setCurrentState('WAIT_END_OF_EXECUTION') |
@@ -550,19 +543,24 b' class IPShellWidget(wx.Panel):' | |||
|
550 | 543 | self.text_ctrl.setPrompt(self.IP.getPrompt()) |
|
551 | 544 | self.text_ctrl.setIndentation(self.IP.getIndentation()) |
|
552 | 545 | self.text_ctrl.setPromptCount(self.IP.getPromptCount()) |
|
553 | rv = self.cout.getvalue() | |
|
554 | if rv: rv = rv.strip('\n') | |
|
555 | self.text_ctrl.showReturned(rv) | |
|
556 | self.cout.truncate(0) | |
|
546 | self.text_ctrl.showPrompt() | |
|
557 | 547 | self.IP.initHistoryIndex() |
|
558 | 548 | self.setCurrentState('IDLE') |
|
559 | 549 | |
|
560 | 550 | def setCurrentState(self, state): |
|
561 | 551 | self.cur_state = state |
|
562 | 552 | self.updateStatusTracker(self.cur_state) |
|
563 | ||
|
553 | #---------------------------- Ipython raw_input ----------------------------------- | |
|
554 | def rawInput(self, prompt=''): | |
|
555 | self.setCurrentState('WAITING_USER_INPUT') | |
|
556 | while self.cur_state != 'WAIT_END_OF_EXECUTION': | |
|
557 | pass | |
|
558 | line = self.text_ctrl.getCurrentLine() | |
|
559 | line = line.split('\n') | |
|
560 | return line[-2] | |
|
561 | ||
|
564 | 562 | #---------------------------- IPython pager --------------------------------------- |
|
565 | def pager(self,text):#,start=0,screen_lines=0,pager_cmd = None): | |
|
563 | def pager(self,text): | |
|
566 | 564 | |
|
567 | 565 | if self.pager_state == 'INIT': |
|
568 | 566 | #print >>sys.__stdout__,"PAGER state:",self.pager_state |
@@ -635,13 +633,21 b' class IPShellWidget(wx.Panel):' | |||
|
635 | 633 | self.pager(self.doc) |
|
636 | 634 | return |
|
637 | 635 | |
|
636 | if self.cur_state == 'WAITING_USER_INPUT': | |
|
637 | line=self.text_ctrl.getCurrentLine() | |
|
638 | self.text_ctrl.write('\n') | |
|
639 | self.setCurrentState('WAIT_END_OF_EXECUTION') | |
|
640 | return | |
|
641 | ||
|
638 | 642 | if event.GetKeyCode() in [ord('q'),ord('Q')]: |
|
639 | 643 | if self.pager_state == 'WAITING': |
|
640 | 644 | self.pager_state = 'DONE' |
|
641 | 645 | self.stateShowPrompt() |
|
642 | 646 | return |
|
643 | ||
|
644 | #scroll_position = self.text_ctrl.GetScrollPos(wx.VERTICAL) | |
|
647 | ||
|
648 | if self.cur_state == 'WAITING_USER_INPUT': | |
|
649 | event.Skip() | |
|
650 | ||
|
645 | 651 | if self.cur_state == 'IDLE': |
|
646 | 652 | if event.KeyCode == wx.WXK_UP: |
|
647 | 653 | history = self.IP.historyBack() |
@@ -669,7 +675,7 b' class IPShellWidget(wx.Panel):' | |||
|
669 | 675 | |
|
670 | 676 | return |
|
671 | 677 | event.Skip() |
|
672 | ||
|
678 | ||
|
673 | 679 | #------------------------ Hook Section ----------------------------------- |
|
674 | 680 | def updateHistoryTracker(self,command_line): |
|
675 | 681 | ''' |
@@ -36,8 +36,7 b' class MyFrame(wx.Frame):' | |||
|
36 | 36 | |
|
37 | 37 | self.ipython_panel = IPShellWidget(self,background_color = "BLACK") |
|
38 | 38 | |
|
39 |
#self.ipython_panel = |
|
|
40 | # background_color = "WHITE") | |
|
39 | #self.ipython_panel = IPShellWidget(self,background_color = "WHITE") | |
|
41 | 40 | |
|
42 | 41 | self.ipython_panel.setHistoryTrackerHook(self.history_panel.write) |
|
43 | 42 | self.ipython_panel.setStatusTrackerHook(self.updateStatus) |
@@ -122,6 +121,7 b' class MyFrame(wx.Frame):' | |||
|
122 | 121 | states = {'IDLE':'Idle', |
|
123 | 122 | 'DO_EXECUTE_LINE':'Send command', |
|
124 | 123 | 'WAIT_END_OF_EXECUTION':'Running command', |
|
124 | 'WAITING_USER_INPUT':'Waiting user input', | |
|
125 | 125 | 'SHOW_DOC':'Showing doc', |
|
126 | 126 | 'SHOW_PROMPT':'Showing prompt'} |
|
127 | 127 | self.statusbar.SetStatusText(states[text], 0) |
General Comments 0
You need to be logged in to leave comments.
Login now