Files
sublime-text-3/Packages/SublimeREPL/repls/execnet_repl.py

112 lines
2.7 KiB
Python

# encoding: utf-8
from . import repl
from queue import Queue
import sys
import execnet
REMOTE_CODE = """
from __future__ import with_statement
from __future__ import division
from __future__ import absolute_import
#if '{activate_file}':
# execfile('{activate_file}', dict(__file__='{activate_file}'))
import code
import sys
import time
import contextlib
import threading
try:
from Queue import Queue
except ImportError:
from queue import Queue # py3
class ChannelOut(object):
def write(self, data):
channel.send(data)
def flush(self):
pass
@contextlib.contextmanager
def redirect_stdio():
orig = (sys.stdout, sys.stderr)
sys.stdout = sys.stderr = ChannelOut()
yield
(sys.stdout, sys.stderr) = orig
class InterceptingConsole(code.InteractiveConsole):
PS1 = "{ps1}"
PS2 = "... "
def __init__(self):
code.InteractiveConsole.__init__(self)
self.input = Queue()
self.output = channel
self.output.send(self.PS1)
def write(self, data):
self.output.send(data)
def push(self, line):
with redirect_stdio():
more = code.InteractiveConsole.push(self, line)
self.output.send(self.PS2 if more else self.PS1)
return more
def run(self):
while True:
line = self.input.get()
if line is None:
break
self.push(line)
ic = InterceptingConsole()
_thread = threading.Thread(target=ic.run)
_thread.start()
channel.setcallback(ic.input.put, endmarker=None)
while not channel.isclosed():
time.sleep(1.0)
"""
class ExecnetRepl(repl.Repl):
TYPE = "execnet_repl"
def __init__(self, encoding, connection_string=None, activate_file="", ps1=">>> "):
super(ExecnetRepl, self).__init__(encoding, "python", "\n", False)
self._connections_string = connection_string
self._ps1 = ps1
self._gw = execnet.makegateway(connection_string)
remote_code = REMOTE_CODE.format(ps1=ps1, activate_file=activate_file)
self._channel = self._gw.remote_exec(remote_code)
self.output = Queue()
self._channel.setcallback(self.output.put, endmarker=None)
self._alive = True
self._killed = False
def name(self):
return "execnet " + self._ps1.split()[0]
def is_alive(self):
return self._alive
def write_bytes(self, bytes):
if self._channel.isclosed():
self._alive = False
else:
self._channel.send(bytes)
def read_bytes(self):
bytes = self.output.get()
if bytes is None:
self._gw.exit()
else:
return bytes
def kill(self):
self._killed = True
self._channel.close()
self._gw.exit()