@@ -502,75 +502,79 @@ def sigint(*args):
502
502
orig_stdin = sys .stdin
503
503
orig_stdout = sys .stdout
504
504
orig_stderr = sys .stderr
505
- try :
506
- # XXX aargh, we have to leave sys.stdin alone for now:
507
- # urwid.display_common.RealTerminal.tty_signal_keys calls
508
- # sys.stdin.fileno() instead of getting stdin passed in as
509
- # raw_display.Screen._term_input_file :(
510
-
511
- # XXX no stdin for you! What to do here?
512
- #sys.stdin = None #FakeStdin(myrepl)
513
- sys .stdout = myrepl
514
- sys .stderr = myrepl
515
-
516
- # This needs more thought. What needs to happen inside the mainloop?
517
- # Note that we need the mainloop started before our stdio
518
- # redirection is hit.
519
- def start (main_loop , user_data ):
520
- if exec_args :
521
- bpargs .exec_code (interpreter , exec_args )
522
- if not options .interactive :
523
- raise urwid .ExitMainLoop ()
524
- if not exec_args :
525
- sys .path .insert (0 , '' )
526
- # this is CLIRepl.startup inlined.
527
- filename = os .environ .get ('PYTHONSTARTUP' )
528
- if filename and os .path .isfile (filename ):
529
- with open (filename , 'r' ) as f :
530
- if py3 :
531
- interpreter .runsource (f .read (), filename , 'exec' )
532
- else :
533
- interpreter .runsource (f .read (), filename , 'exec' ,
534
- encode = False )
535
-
536
- if banner is not None :
537
- repl .write (banner )
538
- repl .write ('\n ' )
539
- myrepl .start ()
540
-
541
- # This bypasses main_loop.set_alarm_in because we must *not*
542
- # hit the draw_screen call (it's unnecessary and slow).
543
- def run_find_coroutine ():
544
- if find_coroutine ():
545
- main_loop .event_loop .alarm (0 , run_find_coroutine )
546
-
547
- run_find_coroutine ()
548
-
549
- loop .set_alarm_in (0 , start )
550
-
551
- while True :
552
- try :
553
- loop .run ()
554
- except KeyboardInterrupt :
555
- # HACK: if we run under a twisted mainloop this should
556
- # never happen: we have a SIGINT handler set.
557
- # If we use the urwid select-based loop we just restart
558
- # that loop if interrupted, instead of trying to cook
559
- # up an equivalent to reactor.callFromThread (which
560
- # is what our Twisted sigint handler does)
561
- loop .set_alarm_in (0 ,
562
- lambda * args : myrepl .keyboard_interrupt ())
563
- continue
564
- break
565
-
566
- if config .hist_length :
567
- histfilename = os .path .expanduser (config .hist_file )
568
- myrepl .rl_history .save (histfilename ,
569
- locale .getpreferredencoding ())
570
- finally :
571
- sys .stdin = orig_stdin
572
- sys .stderr = orig_stderr
573
- sys .stdout = orig_stdout
505
+ # urwid's screen start() and stop() calls currently hit sys.stdin
506
+ # directly (via RealTerminal.tty_signal_keys), so start the screen
507
+ # before swapping sys.std*, and swap them back before restoring
508
+ # the screen. This also avoids crashes if our redirected sys.std*
509
+ # are called before we get around to starting the mainloop
510
+ # (urwid raises an exception if we try to draw to the screen
511
+ # before starting it).
512
+ def run_with_screen_before_mainloop ():
513
+ try :
514
+ # XXX no stdin for you! What to do here?
515
+ sys .stdin = None #FakeStdin(myrepl)
516
+ sys .stdout = myrepl
517
+ sys .stderr = myrepl
518
+
519
+ loop .set_alarm_in (0 , start )
520
+
521
+ while True :
522
+ try :
523
+ loop .run ()
524
+ except KeyboardInterrupt :
525
+ # HACK: if we run under a twisted mainloop this should
526
+ # never happen: we have a SIGINT handler set.
527
+ # If we use the urwid select-based loop we just restart
528
+ # that loop if interrupted, instead of trying to cook
529
+ # up an equivalent to reactor.callFromThread (which
530
+ # is what our Twisted sigint handler does)
531
+ loop .set_alarm_in (
532
+ 0 , lambda * args : myrepl .keyboard_interrupt ())
533
+ continue
534
+ break
535
+
536
+ if config .hist_length :
537
+ histfilename = os .path .expanduser (config .hist_file )
538
+ myrepl .rl_history .save (histfilename ,
539
+ locale .getpreferredencoding ())
540
+
541
+ finally :
542
+ sys .stdin = orig_stdin
543
+ sys .stderr = orig_stderr
544
+ sys .stdout = orig_stdout
545
+
546
+ # This needs more thought. What needs to happen inside the mainloop?
547
+ def start (main_loop , user_data ):
548
+ if exec_args :
549
+ bpargs .exec_code (interpreter , exec_args )
550
+ if not options .interactive :
551
+ raise urwid .ExitMainLoop ()
552
+ if not exec_args :
553
+ sys .path .insert (0 , '' )
554
+ # this is CLIRepl.startup inlined.
555
+ filename = os .environ .get ('PYTHONSTARTUP' )
556
+ if filename and os .path .isfile (filename ):
557
+ with open (filename , 'r' ) as f :
558
+ if py3 :
559
+ interpreter .runsource (f .read (), filename , 'exec' )
560
+ else :
561
+ interpreter .runsource (f .read (), filename , 'exec' ,
562
+ encode = False )
563
+
564
+ if banner is not None :
565
+ repl .write (banner )
566
+ repl .write ('\n ' )
567
+ myrepl .start ()
568
+
569
+ # This bypasses main_loop.set_alarm_in because we must *not*
570
+ # hit the draw_screen call (it's unnecessary and slow).
571
+ def run_find_coroutine ():
572
+ if find_coroutine ():
573
+ main_loop .event_loop .alarm (0 , run_find_coroutine )
574
+
575
+ run_find_coroutine ()
576
+
577
+ loop .screen .run_wrapper (run_with_screen_before_mainloop )
574
578
575
579
if config .flush_output and not options .quiet :
576
580
sys .stdout .write (myrepl .getstdout ())
0 commit comments