@@ -56,6 +56,7 @@ def __init__(self, coderunner, repl):
5656 self .current_line = ''
5757 self .cursor_offset_in_line = 0
5858 self .old_num_lines = 0
59+ self .readline_results = []
5960
6061 def process_event (self , e ):
6162 assert self .has_focus
@@ -83,8 +84,22 @@ def process_event(self, e):
8384 def readline (self ):
8485 self .has_focus = True
8586 self .repl .send_to_stdin (self .current_line )
86- return self .coderunner .wait_and_get_value ()
87+ value = self .coderunner .wait_and_get_value ()
88+ self .readline_results .append (value )
89+ return value
8790
91+ class ReevaluateFakeStdin (object ):
92+ def __init__ (self , fakestdin , repl ):
93+ self .fakestdin = fakestdin
94+ self .repl = repl
95+ self .readline_results = fakestdin .readline_results [:]
96+ def readline (self ):
97+ if self .readline_results :
98+ value = self .readline_results .pop (0 )
99+ else :
100+ value = 'no saved input available'
101+ self .repl .send_to_stdout (value )
102+ return value
88103
89104class Repl (BpythonRepl ):
90105 """
@@ -146,10 +161,13 @@ def __init__(self, locals_=None, config=None, stuff_a_refresh_request=lambda: No
146161 self .cursor_offset_in_line = 0 # from the left, 0 means first char
147162 self .done = True
148163
164+ self .reevaluating = False
165+ self .fake_refresh_request = False
149166 def request_refresh ():
150- self .refresh_requests += 1
151- stuff_a_refresh_request ()
152- self .refresh_requests = 0
167+ if self .reevaluating :
168+ self .fake_refresh_request = True
169+ else :
170+ stuff_a_refresh_request ()
153171 self .stuff_a_refresh_request = request_refresh
154172 self .coderunner = CodeRunner (self .interp , request_refresh )
155173 self .stdout = FakeOutput (self .coderunner , self .send_to_stdout )
@@ -160,7 +178,6 @@ def request_refresh():
160178 self .request_paint_to_clear_screen = False
161179 self .last_events = [None ] * 50
162180 self .presentation_mode = False
163- self .reevaluating = False
164181
165182 self .width = None # will both be set by a window resize event
166183 self .height = None
@@ -207,13 +224,8 @@ def process_event(self, e):
207224 result = None
208225 logging .debug ("processing event %r" , e )
209226 if isinstance (e , events .RefreshRequestEvent ):
210- assert self .refresh_requests > 0
211- self .refresh_requests -= 1
212- assert self .coderunner .code_is_waiting or self .reevaluating
213- if self .coderunner .code_is_waiting :
214- self .run_code_and_maybe_finish ()
215- if self .refresh_requests == 0 and self .reevaluating and not self .stdin .has_focus :
216- self .reevaluate ()
227+ assert self .coderunner .code_is_waiting
228+ self .run_code_and_maybe_finish ()
217229 elif isinstance (e , events .SigIntEvent ):
218230 logging .debug ('received sigint event' )
219231 self .keyboard_interrupt ()
@@ -297,9 +309,6 @@ def process_event(self, e):
297309 self .add_normal_character (e if len (e ) == 1 else e [- 1 ]) #strip control seq
298310 self .update_completion ()
299311
300- if self .reevaluating and self .refresh_requests == 0 and not self .stdin .has_focus :
301- self .stuff_a_refresh_request ()
302-
303312 return result
304313
305314 def on_enter (self , insert_into_history = True ):
@@ -759,16 +768,9 @@ def reprint_line(self, lineno, tokens):
759768 def reevaluate (self , insert_into_history = False ):
760769 """bpython.Repl.undo calls this"""
761770 #TODO This almost works, but stdin.readline() doesn't work yet
762- if not self .reevaluating :
763- self .reevaluating = self .reevaluation_generator (insert_into_history = insert_into_history )
764- try :
765- self .reevaluating .next ()
766- except StopIteration :
767- self .reevaluating = False
768-
769- def reevaluation_generator (self , insert_into_history ):
770771 #TODO other implementations have a enter no-history method, could do
771772 # that instead of clearing history and getting it rewritten
773+
772774 old_logical_lines = self .history
773775 self .history = []
774776 self .display_lines = []
@@ -782,10 +784,17 @@ def reevaluation_generator(self, insert_into_history):
782784 self .display_buffer = []
783785 self .highlighted_paren = None
784786
787+ self .reevaluating = True
788+ sys .stdin = ReevaluateFakeStdin (self .stdin , self )
785789 for line in old_logical_lines :
786790 self ._current_line = line
787791 self .on_enter (insert_into_history = insert_into_history )
788- yield line
792+ while self .fake_refresh_request :
793+ self .fake_refresh_request = False
794+ self .process_event (events .RefreshRequestEvent ())
795+ sys .stdin = self .stdin
796+ self .reevaluating = False
797+
789798 self .cursor_offset_in_line = 0
790799 self ._current_line = ''
791800
0 commit comments