From bdf31d8011a7bcf26bf5d1155dd1bdcd3fc88e0c 2013-06-01 17:45:22 From: Min RK Date: 2013-06-01 17:45:22 Subject: [PATCH] Merge pull request #3366 from minrk/rmfrontend remove long-dead zmq frontend.py and completer.py These were really just demos to begin with, and should never have been included as library code. closes #3365 --- diff --git a/IPython/kernel/zmq/completer.py b/IPython/kernel/zmq/completer.py deleted file mode 100644 index 65ba51d..0000000 --- a/IPython/kernel/zmq/completer.py +++ /dev/null @@ -1,91 +0,0 @@ -"""Tab-completion over zmq""" - -# Trying to get print statements to work during completion, not very -# successfully... -from __future__ import print_function - -import itertools -try: - import readline -except ImportError: - readline = None -import rlcompleter -import time - -import session - -class KernelCompleter(object): - """Kernel-side completion machinery.""" - def __init__(self, namespace): - self.namespace = namespace - self.completer = rlcompleter.Completer(namespace) - - def complete(self, line, text): - # We'll likely use linel later even if now it's not used for anything - matches = [] - complete = self.completer.complete - for state in itertools.count(): - comp = complete(text, state) - if comp is None: - break - matches.append(comp) - return matches - - -class ClientCompleter(object): - """Client-side completion machinery. - - How it works: self.complete will be called multiple times, with - state=0,1,2,... When state=0 it should compute ALL the completion matches, - and then return them for each value of state.""" - - def __init__(self, client, session, socket): - # ugly, but we get called asynchronously and need access to some - # client state, like backgrounded code - assert readline is not None, "ClientCompleter depends on readline" - self.client = client - self.session = session - self.socket = socket - self.matches = [] - - def request_completion(self, text): - # Get full line to give to the kernel in case it wants more info. - line = readline.get_line_buffer() - # send completion request to kernel - msg = self.session.send(self.socket, - 'complete_request', - dict(text=text, line=line)) - - # Give the kernel up to 0.5s to respond - for i in range(5): - ident,rep = self.session.recv(self.socket) - rep = session.Message(rep) - if rep is not None and rep.msg_type == 'complete_reply': - matches = rep.content.matches - break - time.sleep(0.1) - else: - # timeout - print ('TIMEOUT') # Can't see this message... - matches = None - return matches - - def complete(self, text, state): - - if self.client.backgrounded > 0: - print("\n[Not completing, background tasks active]") - print(readline.get_line_buffer(), end='') - return None - - if state==0: - matches = self.request_completion(text) - if matches is None: - self.matches = [] - print('WARNING: Kernel timeout on tab completion.') - else: - self.matches = matches - - try: - return self.matches[state] - except IndexError: - return None diff --git a/IPython/kernel/zmq/frontend.py b/IPython/kernel/zmq/frontend.py deleted file mode 100755 index bd7f682..0000000 --- a/IPython/kernel/zmq/frontend.py +++ /dev/null @@ -1,199 +0,0 @@ -#!/usr/bin/env python -"""A simple interactive frontend that talks to a kernel over 0MQ. -""" - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- -from __future__ import print_function - -# stdlib -import cPickle as pickle -import code -import readline -import sys -import time -import uuid - -# our own -import zmq -import session -import completer -from IPython.utils.localinterfaces import LOCALHOST -from IPython.kernel.zmq.session import Message - -#----------------------------------------------------------------------------- -# Classes and functions -#----------------------------------------------------------------------------- - -class Console(code.InteractiveConsole): - - def __init__(self, locals=None, filename="", - session = session, - request_socket=None, - sub_socket=None): - code.InteractiveConsole.__init__(self, locals, filename) - self.session = session - self.request_socket = request_socket - self.sub_socket = sub_socket - self.backgrounded = 0 - self.messages = {} - - # Set tab completion - self.completer = completer.ClientCompleter(self, session, request_socket) - readline.parse_and_bind('tab: complete') - readline.parse_and_bind('set show-all-if-ambiguous on') - readline.set_completer(self.completer.complete) - - # Set system prompts - sys.ps1 = 'Py>>> ' - sys.ps2 = ' ... ' - sys.ps3 = 'Out : ' - # Build dict of handlers for message types - self.handlers = {} - for msg_type in ['pyin', 'pyout', 'pyerr', 'stream']: - self.handlers[msg_type] = getattr(self, 'handle_%s' % msg_type) - - def handle_pyin(self, omsg): - if omsg.parent_header.session == self.session.session: - return - c = omsg.content.code.rstrip() - if c: - print('[IN from %s]' % omsg.parent_header.username) - print(c) - - def handle_pyout(self, omsg): - #print omsg # dbg - if omsg.parent_header.session == self.session.session: - print("%s%s" % (sys.ps3, omsg.content.data)) - else: - print('[Out from %s]' % omsg.parent_header.username) - print(omsg.content.data) - - def print_pyerr(self, err): - print(err.etype,':', err.evalue, file=sys.stderr) - print(''.join(err.traceback), file=sys.stderr) - - def handle_pyerr(self, omsg): - if omsg.parent_header.session == self.session.session: - return - print('[ERR from %s]' % omsg.parent_header.username, file=sys.stderr) - self.print_pyerr(omsg.content) - - def handle_stream(self, omsg): - if omsg.content.name == 'stdout': - outstream = sys.stdout - else: - outstream = sys.stderr - print('*ERR*', end=' ', file=outstream) - print(omsg.content.data, end=' ', file=outstream) - - def handle_output(self, omsg): - handler = self.handlers.get(omsg.msg_type, None) - if handler is not None: - handler(omsg) - - def recv_output(self): - while True: - ident,msg = self.session.recv(self.sub_socket) - if msg is None: - break - self.handle_output(Message(msg)) - - def handle_reply(self, rep): - # Handle any side effects on output channels - self.recv_output() - # Now, dispatch on the possible reply types we must handle - if rep is None: - return - if rep.content.status == 'error': - self.print_pyerr(rep.content) - elif rep.content.status == 'aborted': - print("ERROR: ABORTED", file=sys.stderr) - ab = self.messages[rep.parent_header.msg_id].content - if 'code' in ab: - print(ab.code, file=sys.stderr) - else: - print(ab, file=sys.stderr) - - def recv_reply(self): - ident,rep = self.session.recv(self.request_socket) - mrep = Message(rep) - self.handle_reply(mrep) - return mrep - - def runcode(self, code): - # We can't pickle code objects, so fetch the actual source - src = '\n'.join(self.buffer) - - # for non-background inputs, if we do have previoiusly backgrounded - # jobs, check to see if they've produced results - if not src.endswith(';'): - while self.backgrounded > 0: - #print 'checking background' - rep = self.recv_reply() - if rep: - self.backgrounded -= 1 - time.sleep(0.05) - - # Send code execution message to kernel - omsg = self.session.send(self.request_socket, - 'execute_request', dict(code=src)) - self.messages[omsg.header.msg_id] = omsg - - # Fake asynchronicity by letting the user put ';' at the end of the line - if src.endswith(';'): - self.backgrounded += 1 - return - - # For foreground jobs, wait for reply - while True: - rep = self.recv_reply() - if rep is not None: - break - self.recv_output() - time.sleep(0.05) - else: - # We exited without hearing back from the kernel! - print('ERROR!!! kernel never got back to us!!!', file=sys.stderr) - - -class InteractiveClient(object): - def __init__(self, session, request_socket, sub_socket): - self.session = session - self.request_socket = request_socket - self.sub_socket = sub_socket - self.console = Console(None, '', - session, request_socket, sub_socket) - - def interact(self): - self.console.interact() - - -def main(): - # Defaults - #ip = '192.168.2.109' - ip = LOCALHOST - #ip = '99.146.222.252' - port_base = 5575 - connection = ('tcp://%s' % ip) + ':%i' - req_conn = connection % port_base - sub_conn = connection % (port_base+1) - - # Create initial sockets - c = zmq.Context() - request_socket = c.socket(zmq.DEALER) - request_socket.connect(req_conn) - - sub_socket = c.socket(zmq.SUB) - sub_socket.connect(sub_conn) - sub_socket.setsockopt(zmq.SUBSCRIBE, '') - - # Make session and user-facing client - sess = session.Session() - client = InteractiveClient(sess, request_socket, sub_socket) - client.interact() - - -if __name__ == '__main__': - main()