[pypy-svn] r45823 - in pypy/branch/pypy-more-rtti-inprogress/translator/sandbox: . test

arigo at codespeak.net arigo at codespeak.net
Fri Aug 17 18:22:58 CEST 2007


Author: arigo
Date: Fri Aug 17 18:22:56 2007
New Revision: 45823

Modified:
   pypy/branch/pypy-more-rtti-inprogress/translator/sandbox/rsandbox.py
   pypy/branch/pypy-more-rtti-inprogress/translator/sandbox/sandlib.py
   pypy/branch/pypy-more-rtti-inprogress/translator/sandbox/test/test_sandbox.py
Log:
Support for sending RPython exceptions of common classes into the
sandboxed process.


Modified: pypy/branch/pypy-more-rtti-inprogress/translator/sandbox/rsandbox.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/translator/sandbox/rsandbox.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/translator/sandbox/rsandbox.py	Fri Aug 17 18:22:56 2007
@@ -96,11 +96,22 @@
     # check for errors
     error = load_int(loader)
     if error != 0:
-        raise IOError     # XXX add support to raise the correct exception
+        reraise_error(error, loader)
     else:
         # no exception; the caller will decode the actual result
         return loader
 
+def reraise_error(error, loader):
+    if   error == 1: raise OSError(load_int(loader), "external error")
+    elif error == 2: raise IOError
+    elif error == 3: raise OverflowError
+    elif error == 4: raise ValueError
+    elif error == 5: raise ZeroDivisionError
+    elif error == 6: raise MemoryError
+    elif error == 7: raise KeyError
+    elif error == 8: raise IndexError
+    else:            raise RuntimeError
+
 def not_implemented_stub(msg):
     STDERR = 2
     buf = rffi.str2charp(msg + '\n')

Modified: pypy/branch/pypy-more-rtti-inprogress/translator/sandbox/sandlib.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/translator/sandbox/sandlib.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/translator/sandbox/sandlib.py	Fri Aug 17 18:22:56 2007
@@ -32,6 +32,30 @@
         g.write(''.join(buf))
     g.flush()
 
+# keep the table in sync with rsandbox.reraise_error()
+EXCEPTION_TABLE = [
+    (1, OSError),
+    (2, IOError),
+    (3, OverflowError),
+    (4, ValueError),
+    (5, ZeroDivisionError),
+    (6, MemoryError),
+    (7, KeyError),
+    (8, IndexError),
+    (9, RuntimeError),
+    ]
+
+def write_exception(g, exception):
+    for i, excclass in EXCEPTION_TABLE:
+        if isinstance(exception, excclass):
+            write_message(g, i)
+            if excclass is OSError:
+                write_message(g, exception.errno)
+            break
+    else:
+        raise Exception("cannot report %s exception to the subprocess" % (
+            exception.__class__.__name__,))
+
 
 class SandboxedProc(object):
     """Base class to control a sandboxed subprocess.

Modified: pypy/branch/pypy-more-rtti-inprogress/translator/sandbox/test/test_sandbox.py
==============================================================================
--- pypy/branch/pypy-more-rtti-inprogress/translator/sandbox/test/test_sandbox.py	(original)
+++ pypy/branch/pypy-more-rtti-inprogress/translator/sandbox/test/test_sandbox.py	Fri Aug 17 18:22:56 2007
@@ -5,14 +5,18 @@
 from pypy.rpython.lltypesystem import rffi
 from pypy.translator.interactive import Translation
 from pypy.translator.sandbox.sandlib import read_message, write_message
+from pypy.translator.sandbox.sandlib import write_exception
 
 def expect(f, g, fnname, args, result, resulttype=None):
     msg = read_message(f, timeout=10.0)
     assert msg == fnname
     msg = read_message(f, timeout=10.0)
     assert msg == args
-    write_message(g, 0)
-    write_message(g, result, resulttype)
+    if isinstance(result, Exception):
+        write_exception(g, result)
+    else:
+        write_message(g, 0)
+        write_message(g, result, resulttype)
 
 
 def test_sandbox_1():
@@ -95,6 +99,24 @@
     f.close()
     assert tail == ""
 
+def test_oserror():
+    def entry_point(argv):
+        try:
+            os.stat("somewhere")
+        except OSError, e:
+            os.close(e.errno)    # nonsense, just to see outside
+        return 0
+
+    t = Translation(entry_point, backend='c', standalone=True, sandbox=True)
+    exe = t.compile()
+    g, f = os.popen2(exe, "t", 0)
+    expect(f, g, "ll_os.ll_os_stat", ("somewhere",), OSError(6321, "egg"))
+    expect(f, g, "ll_os.ll_os_close", (6321,), None)
+    g.close()
+    tail = f.read()
+    f.close()
+    assert tail == ""
+
 class TestPrintedResults:
 
     def run(self, entry_point, args, expected):



More information about the Pypy-commit mailing list