Skip to content

Commit eadd2e7

Browse files
refactor stdout and stdin
--HG-- branch : scroll-frontend
1 parent a34dc60 commit eadd2e7

File tree

2 files changed

+42
-32
lines changed

2 files changed

+42
-32
lines changed

bpython/scrollfrontend/coderunner.py

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,20 @@ def running(self):
2121
return self.source and self.code_thread
2222

2323
def load_code(self, source):
24+
"""Prep code to be run"""
2425
self.source = source
2526
self.code_thread = None
2627

27-
def run_code(self, input=None):
28+
def _unload_code(self):
29+
"""Called when done running code"""
30+
self.source = None
31+
self.code_thread = None
32+
self.code_is_waiting = False
33+
34+
def run_code(self, for_code=None):
2835
"""Returns Truthy values if code finishes, False otherwise
2936
37+
if for_code is provided, send that value to the code thread
3038
if source code is complete, returns "done"
3139
if source code is incomplete, returns "unfinished"
3240
"""
@@ -38,49 +46,51 @@ def run_code(self, input=None):
3846
else:
3947
assert self.code_is_waiting
4048
self.code_is_waiting = False
41-
self.responses_for_code_thread.put(input)
49+
self.responses_for_code_thread.put(for_code)
4250

4351
request = self.requests_from_code_thread.get()
44-
if request[0] == 'done':
45-
self.source = None
46-
self.code_thread = None
47-
self.code_is_waiting = False
48-
return 'unfinished' if request[1] else 'done'
49-
else:
50-
method, args, kwargs = request
52+
if request in ['wait', 'refresh']:
5153
self.code_is_waiting = True
52-
if method:
53-
method(*args, **kwargs)
54+
if request == 'refresh':
5455
self.stuff_a_refresh_request()
5556
return False
57+
elif request in ['done', 'unfinished']:
58+
self._unload_code()
59+
return request
60+
else:
61+
raise ValueError("Not a valid request_from_code_thread value: %r" % request)
5662

5763
def _blocking_run_code(self):
5864
unfinished = self.interp.runsource(self.source)
59-
self.requests_from_code_thread.put(('done', unfinished))
60-
def _blocking_wait_for(self, method=lambda: None, args=[], kwargs={}):
61-
"""The method the code would like to be called, or nothing
65+
self.requests_from_code_thread.put('unfinished' if unfinished else 'done')
66+
67+
def wait_and_get_value(self):
68+
"""Return the argument passed in to .run_code(for_code)
6269
6370
Nothing means calls to run_code must be...
64-
does this thing even have a point? is it required for stdout.write?
6571
"""
66-
self.requests_from_code_thread.put((method, args, kwargs))
72+
self.requests_from_code_thread.put('wait')
73+
return self.responses_for_code_thread.get()
74+
75+
def refresh_and_get_value(self):
76+
"""Returns the argument passed in to .run_code(for_code) """
77+
self.requests_from_code_thread.put('refresh')
6778
return self.responses_for_code_thread.get()
6879

6980
class FakeOutput(object):
7081
def __init__(self, coderunner, please):
7182
self.coderunner = coderunner
7283
self.please = please
7384
def write(self, *args, **kwargs):
74-
return self.coderunner._blocking_wait_for(self.please, args, kwargs)
85+
self.please(*args, **kwargs)
86+
return self.coderunner.refresh_and_get_value()
7587

7688
if __name__ == '__main__':
7789
orig_stdout = sys.stdout
7890
orig_stderr = sys.stderr
7991
c = CodeRunner(stuff_a_refresh_request=lambda: orig_stdout.flush() or orig_stderr.flush())
8092
stdout = FakeOutput(c, orig_stdout.write)
81-
stderr = FakeOutput(c, orig_stderr.write)
8293
sys.stdout = stdout
83-
sys.stderr = stderr
8494
c.load_code('1 + 1')
8595
c.run_code()
8696
c.run_code()

bpython/scrollfrontend/repl.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
import logging
55
import code
66
import threading
7-
import Queue
8-
from cStringIO import StringIO
9-
import traceback
107
import subprocess
118
import tempfile
129

@@ -79,14 +76,15 @@ def process_event(self, e):
7976
self.has_focus = False
8077
self.current_line = ''
8178
self.cursor_offset_in_line = 0
82-
self.repl.coderunner.run_code(input=line)
79+
#self.repl.coderunner.run_code(for_code=line)
80+
self.repl.run_code_and_maybe_finish(for_code=line)
8381
else:
8482
self.repl.send_to_stdin(self.current_line)
8583

8684
def readline(self):
8785
self.has_focus = True
8886
self.repl.send_to_stdin(self.current_line)
89-
return self.coderunner._blocking_wait_for(None)
87+
return self.coderunner.wait_and_get_value()
9088

9189

9290
class Repl(BpythonRepl):
@@ -196,7 +194,7 @@ def process_event(self, e):
196194

197195
logging.debug("processing event %r", e)
198196
if isinstance(e, events.RefreshRequestEvent):
199-
self.finish_command_if_done()
197+
self.run_code_and_maybe_finish()
200198
return
201199
self.last_events.append(e)
202200
self.last_events.pop(0)
@@ -413,7 +411,6 @@ def push(self, line, insert_into_history=True):
413411
logging.debug('running %r in interpreter', self.buffer)
414412
code_to_run = '\n'.join(self.buffer)
415413
self.saved_indent = indent
416-
self.saved_line = line
417414

418415
#current line not added to display buffer if quitting #TODO I don't understand this comment
419416
if self.config.syntax:
@@ -433,11 +430,13 @@ def push(self, line, insert_into_history=True):
433430
self.cursor_offset_in_line = 0
434431

435432
self.coderunner.load_code(code_to_run)
436-
self.finish_command_if_done()
433+
self.run_code_and_maybe_finish()
437434

438-
def finish_command_if_done(self):
439-
r = self.coderunner.run_code()
435+
def run_code_and_maybe_finish(self, for_code=None):
436+
r = self.coderunner.run_code(for_code=for_code)
440437
if r:
438+
logging.debug("----- Running finish command stuff -----")
439+
logging.debug("run_code return value: %r", r)
441440
unfinished = r == 'unfinished'
442441
err = True #TODO implement this properly - via interp.write_error I suppose
443442

@@ -462,7 +461,7 @@ def unhighlight_paren(self):
462461
logging.debug('trying to unhighlight a paren on line %r', lineno)
463462
logging.debug('with these tokens: %r', saved_tokens)
464463
new = bpythonparse(format(saved_tokens, self.formatter))
465-
self.display_buffer[lineno][:len(new)] = new
464+
self.display_buffer[lineno] = self.display_buffer[lineno].setslice(0, len(new), new)
466465

467466

468467
## formatting, output
@@ -526,9 +525,10 @@ def display_line_with_prompt(self):
526525

527526
@property
528527
def current_cursor_line(self):
529-
530-
return (self.current_output_line +
528+
value = (self.current_output_line +
531529
'' if self.coderunner.running else self.display_line_with_prompt)
530+
logging.debug('current cursor line: %r', value)
531+
return value
532532

533533
@property
534534
def current_output_line(self):

0 commit comments

Comments
 (0)