Repository: ipython/ipython

Issue:
zmq frontend
Hello,

Trying to run the zmq frontend.py to test the kernalapp.py

I get this

```
system-process:zmq ericjang$ python frontend.py 
Python 2.7.1 (r271:86832, Jul 31 2011, 19:30:53) 
[GCC 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(Console)
Py>>> x = 1
Traceback (most recent call last):
  File "frontend.py", line 199, in <module>
    main()
  File "frontend.py", line 195, in main
    client.interact()
  File "frontend.py", line 170, in interact
    self.console.interact()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/code.py", line 243, in interact
    more = self.push(line)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/code.py", line 265, in push
    more = self.runsource(source, self.filename)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/code.py", line 87, in runsource
    self.runcode(code)
  File "frontend.py", line 142, in runcode
    self.messages[omsg.header.msg_id] = omsg
AttributeError: 'dict' object has no attribute 'header'
```



Discussion:

Resolving patch:
diff --git a/IPython/kernel/zmq/completer.py b/IPython/kernel/zmq/completer.py
deleted file mode 100644
--- 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
--- 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="<console>",
-                 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, '<zmq-console>',
-                               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()


Test patch: