X Tutup
Skip to content

Commit 45d9b9e

Browse files
add docs to coderunner
1 parent a46e054 commit 45d9b9e

File tree

1 file changed

+46
-6
lines changed

1 file changed

+46
-6
lines changed

bpython/curtsiesfrontend/coderunner.py

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,72 @@
1+
"""For running Python code that could interrupt itself at any time
2+
3+
in order to, for example, ask for a read on stdin, or a write on stdout
4+
5+
The CodeRunner spawns a greenlet to run code it, and that code can suspend
6+
its own execution to ask the main thread to refresh the display or get information.
7+
"""
8+
19
import code
210
import signal
311
import sys
412
import greenlet
513
import logging
614

715
class SigintHappened(object):
8-
pass
16+
"""If this class is returned, a SIGINT happened while the main thread"""
917

1018
class SystemExitFromCodeThread(SystemExit):
19+
"""If this class is returned, a SystemExit happened while in the code thread"""
1120
pass
1221

1322
class CodeRunner(object):
14-
"""Runs user code in an interpreter, taking care of stdout/in/err"""
23+
"""Runs user code in an interpreter.
24+
25+
Running code requests a refresh by calling refresh_and_get_value(), which
26+
suspends execution of the code and switches back to the main thread
27+
28+
After load_code() is called with the source code to be run,
29+
the run_code() method should be called to start running the code.
30+
The running code may request screen refreshes and user input
31+
by calling the refresh_and_get_value and wait_and_get_value calls
32+
respectively. When these are called, the running source code cedes
33+
control, and the current run_code() method call returns.
34+
35+
The return value of run_code() determines whether the method ought
36+
to be called again to complete execution of the source code.
37+
38+
Once the screen refresh has occurred or the requested user input
39+
has been gathered, run_code() should be called again, passing in any
40+
requested user input. This continues until run_code returns 'done'.
41+
42+
Question: How does the caller of run_code know that user input ought
43+
to be returned?
44+
"""
1545
def __init__(self, interp=None, stuff_a_refresh_request=lambda:None):
46+
"""
47+
interp is an interpreter object to use. By default a new one is
48+
created.
49+
50+
stuff_a_refresh_request is a function that will be called each time
51+
the running code asks for a refresh - to, for example, update the screen.
52+
"""
1653
self.interp = interp or code.InteractiveInterpreter()
1754
self.source = None
1855
self.main_greenlet = greenlet.getcurrent()
1956
self.code_greenlet = None
2057
self.stuff_a_refresh_request = stuff_a_refresh_request
21-
self.code_is_waiting = False
58+
self.code_is_waiting = False # waiting for response from main thread
2259
self.sigint_happened = False
2360
self.orig_sigint_handler = None
2461

2562
@property
2663
def running(self):
64+
"""Returns greenlet if code has been loaded greenlet has been started"""
2765
return self.source and self.code_greenlet
2866

2967
def load_code(self, source):
3068
"""Prep code to be run"""
69+
assert self.source is None, "you shouldn't load code when some is already running"
3170
self.source = source
3271
self.code_greenlet = None
3372

@@ -77,6 +116,7 @@ def run_code(self, for_code=None):
77116
raise ValueError("Not a valid value from code greenlet: %r" % request)
78117

79118
def sigint_handler(self, *args):
119+
"""SIGINT handler to use while code is running or request being fufilled"""
80120
if greenlet.getcurrent() is self.code_greenlet:
81121
logging.debug('sigint while running user code!')
82122
raise KeyboardInterrupt()
@@ -109,11 +149,11 @@ def refresh_and_get_value(self):
109149
return value
110150

111151
class FakeOutput(object):
112-
def __init__(self, coderunner, please):
152+
def __init__(self, coderunner, on_write):
113153
self.coderunner = coderunner
114-
self.please = please
154+
self.on_write = on_write
115155
def write(self, *args, **kwargs):
116-
self.please(*args, **kwargs)
156+
self.on_write(*args, **kwargs)
117157
return self.coderunner.refresh_and_get_value()
118158
def writelines(self, l):
119159
for s in l:

0 commit comments

Comments
 (0)
X Tutup