[pypy-svn] r39724 - in pypy/dist/pypy/translator/js/examples/console: . data test

fijal at codespeak.net fijal at codespeak.net
Fri Mar 2 17:44:06 CET 2007


Author: fijal
Date: Fri Mar  2 17:44:04 2007
New Revision: 39724

Added:
   pypy/dist/pypy/translator/js/examples/console/session.py
   pypy/dist/pypy/translator/js/examples/console/test/test_session.py
Modified:
   pypy/dist/pypy/translator/js/examples/console/client.py
   pypy/dist/pypy/translator/js/examples/console/console.py
   pypy/dist/pypy/translator/js/examples/console/data/console.html
   pypy/dist/pypy/translator/js/examples/console/test/test_console.py
Log:
Add some improvements to console example


Modified: pypy/dist/pypy/translator/js/examples/console/client.py
==============================================================================
--- pypy/dist/pypy/translator/js/examples/console/client.py	(original)
+++ pypy/dist/pypy/translator/js/examples/console/client.py	Fri Mar  2 17:44:04 2007
@@ -20,20 +20,13 @@
 
 def refresh_console(msg):
     inp_elem = dom.document.getElementById("inp")
-    inp_elem.disabled = False
+    #inp_elem.disabled = False
     inp_elem.scrollIntoView()
     log(msg[0])
     if msg[0] == "refresh":
         data = msg[1]
         log(data)
-        if data.endswith(">>> ") or data.endswith("... "):
-            # prove positive slice here
-            l = len(data) - 4
-            assert l >= 0
-            glob.prompt = data[l:]
-            data = data[:l]
-        else:
-            exported_methods.refresh_empty(glob.sess_id, refresh_console)
+        exported_methods.refresh_empty(glob.sess_id, refresh_console)
         add_text(data)
     elif msg[0] == 'disconnect':
         dom.document.getElementById("error").innerHTML = "ERROR! disconnected"
@@ -44,7 +37,7 @@
 
 def empty_callback(msg):
     inp_elem = dom.document.getElementById("inp")
-    inp_elem.disabled = False
+    #inp_elem.disabled = False
     inp_elem.scrollIntoView()
 
 def keypressed(key):
@@ -53,12 +46,11 @@
         inp_elem = dom.document.getElementById("inp")
         cmd = inp_elem.value
         inp_elem.value = ''
-        inp_elem.disabled = True
-        add_text(glob.prompt + cmd + "\n")
+        add_text(cmd + "\n")
         #if not cmd:
         #    exported_methods.refresh(glob.sess_id, cmd, empty_callback)
         #else:
-        exported_methods.refresh(glob.sess_id, cmd, refresh_console)
+        exported_methods.refresh(glob.sess_id, cmd + "\n", refresh_console)
 
 def console_onload():
     createLoggingPane(True)

Modified: pypy/dist/pypy/translator/js/examples/console/console.py
==============================================================================
--- pypy/dist/pypy/translator/js/examples/console/console.py	(original)
+++ pypy/dist/pypy/translator/js/examples/console/console.py	Fri Mar  2 17:44:04 2007
@@ -9,6 +9,7 @@
 from pypy.translator.js.main import rpython2javascript
 from pypy.translator.js.lib.support import callback
 from pypy.translator.js import commproxy
+from pypy.translator.js.examples.console.session import Interpreter
 
 commproxy.USE_MOCHIKIT = True
 
@@ -19,35 +20,18 @@
     import client
     return rpython2javascript(client, FUNCTION_LIST)
 
-def run_console(python):
-    pipe = subprocess.Popen([python, "-u", "-i"], stdout=subprocess.PIPE,
-                            stdin=subprocess.PIPE, stderr=subprocess.STDOUT,
-                            close_fds=True, bufsize=0)
-    # a bit of a POSIX voodoo
-    fcntl.fcntl(pipe.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)
-    return pipe
-
-def interact(pipe, to_write=None):
-    if to_write is not None:
-        pipe.stdin.write(to_write + "\n")
-    try:
-        return pipe.stdout.read()
-    except IOError:
-        time.sleep(.1)
-        return ""
-
 class Sessions(object):
     def __init__(self):
         self.sessions = {}
 
     def new_session(self):
-        pipe = run_console("python")
-        self.sessions[pipe.pid] = pipe
-        return pipe.pid
+        ip = Interpreter("python")
+        self.sessions[ip.pid] = ip
+        return ip.pid
 
     def update_session(self, pid, to_write=None):
-        pipe = self.sessions[pid]
-        return interact(pipe, to_write)
+        ip = self.sessions[pid]
+        return ip.interact(to_write)
 
 # We hack here, cause in exposed methods we don't have global 'server'
 # state
@@ -61,6 +45,7 @@
 
     @callback(retval=[str])
     def refresh(self, pid=0, to_write=""):
+        print "Refresh %s" % to_write
         try:
             return ["refresh", sessions.update_session(int(pid), to_write)]
         except KeyError:
@@ -68,6 +53,7 @@
 
     @callback(retval=[str])
     def refresh_empty(self, pid=0):
+        print "Empty refresh"
         try:
             return ["refresh", sessions.update_session(int(pid), None)]
         except KeyError:

Modified: pypy/dist/pypy/translator/js/examples/console/data/console.html
==============================================================================
--- pypy/dist/pypy/translator/js/examples/console/data/console.html	(original)
+++ pypy/dist/pypy/translator/js/examples/console/data/console.html	Fri Mar  2 17:44:04 2007
@@ -1,7 +1,7 @@
 <html>
 <head>
    <script type="text/javascript" src="source.js"></script>
-   <script src="http://mochikit.com/MochiKit/MochiKit.js" type="text/javascript"></script>
+   <script src="MochiKit/MochiKit.js" type="text/javascript"></script>
    <title>Console</title>
    <style>
    </style>

Added: pypy/dist/pypy/translator/js/examples/console/session.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/js/examples/console/session.py	Fri Mar  2 17:44:04 2007
@@ -0,0 +1,81 @@
+
+""" In this file we define all necessary stuff
+build around subprocess to run python console in it
+"""
+
+TIMEOUT = 10
+
+""" The idea behind is that we create xmlhttprequest immediataly
+and reply with new data (if available) or reply anyway
+after TIMEOUT
+"""
+
+import py
+import subprocess
+from Queue import Queue
+from pypeers.greensock2 import autogreenlet, sleep, wait, meetingpoint
+from pypeers.pipe.fd import FDInput
+
+def timeout_read(fd, timeout):
+    read = []
+    giver, accepter = meetingpoint()
+    
+    def timeout_fun():
+        sleep(timeout)
+        giver.give(None)
+        g_read.interrupt()
+
+    def read_fun():
+        giver.give(fd.recv(1024))
+        g_timer.interrupt()
+
+    g_timer = autogreenlet(timeout_fun)
+    g_read = autogreenlet(read_fun)
+    return accepter.accept()
+    
+class Interpreter(object):
+    def __init__(self, python, timeout=TIMEOUT):
+        pipe = subprocess.Popen([python, "-u", "-i"], stdout=subprocess.PIPE,
+                            stdin=subprocess.PIPE, stderr=subprocess.STDOUT,
+                            close_fds=True, bufsize=0)
+        self.pipe = pipe
+        self.read_fd = FDInput(self.pipe.stdout.fileno())
+        self.pid = pipe.pid
+        self.timeout = timeout
+
+    def interact(self, to_write=None):
+        if to_write is not None:
+            self.pipe.stdin.write(to_write)
+        return timeout_read(self.read_fd, self.timeout)
+
+    def close(self):
+        self.pipe.stdin.close()
+        # XXX: some sane way of doing wait here? (note that wait
+        #      is blocking, which means it eats all our clean interface)
+        #self.pipe.wait()
+
+class InterpreterManager(object):
+    pass
+
+#class Sessions(object):
+#    def __init__(self):
+#        self.sessions = {}
+
+#    def new_session(self, python="python"):
+#        pipe = run_console(python)
+#        self.sessions[pipe.pid] = pipe
+#        return pipe.pid
+
+#    def update_session(self, pid, to_write=None):
+#        pipe = self.sessions[pid]
+#        return interact(pipe, to_write)
+
+
+#def interact(pipe, to_write=None):
+#    if to_write is not None:
+#        pipe.stdin.write(to_write + "\n")
+#    try:
+#        return pipe.stdout.read()
+#    except IOError:
+#        time.sleep(.1)
+#        return ""

Modified: pypy/dist/pypy/translator/js/examples/console/test/test_console.py
==============================================================================
--- pypy/dist/pypy/translator/js/examples/console/test/test_console.py	(original)
+++ pypy/dist/pypy/translator/js/examples/console/test/test_console.py	Fri Mar  2 17:44:04 2007
@@ -4,6 +4,8 @@
 def test_run_console():
     """ Check if we can read anything
     """
+    import py
+    py.test.skip("XXX")
     pipe = console.run_console("python")
     pipe.stdin.close()
     t = False

Added: pypy/dist/pypy/translator/js/examples/console/test/test_session.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/translator/js/examples/console/test/test_session.py	Fri Mar  2 17:44:04 2007
@@ -0,0 +1,35 @@
+
+""" Various tests around interpreter in a subprocess
+"""
+
+from pypeers.greensock2 import autogreenlet, wait, sleep, ConnexionClosed
+from pypeers.pipe.fd import FDInput
+from pypy.translator.js.examples.console.session import Interpreter
+import py
+
+def test_greensock_reader_timeouter():
+    i = Interpreter("python", timeout=3)
+    while not i.interact().endswith(">>> "):
+        pass
+    assert i.interact() is None
+    assert i.interact("a\n") is not None
+
+def test_two_interpreters():
+    i = Interpreter("python", timeout=3)
+    i2 = Interpreter("python", timeout=3)
+    while not i.interact().endswith(">>> "):
+        pass
+    while not i2.interact().endswith(">>> "):
+        pass
+    l = []
+
+    def f():
+        l.append(i.interact("import time;time.sleep(1)\n"))
+    def g():
+        l.append(i2.interact("a\n"))
+
+    g_f = autogreenlet(f)
+    g_g = autogreenlet(g)
+    wait()
+    assert len(l) == 2
+    assert l[1].startswith(">>")



More information about the Pypy-commit mailing list