[pypy-commit] pypy py3k: fix greenlet exception handling: this has to normalize 3 item exception args

pjenvey noreply at buildbot.pypy.org
Sat Jul 20 02:21:16 CEST 2013


Author: Philip Jenvey <pjenvey at underboss.org>
Branch: py3k
Changeset: r65492:6a0b8e7eaf5d
Date: 2013-07-19 17:18 -0700
http://bitbucket.org/pypy/pypy/changeset/6a0b8e7eaf5d/

Log:	fix greenlet exception handling: this has to normalize 3 item
	exception args without py2's 2 or 3 expression raise statement, so
	do it w/ a stupid new __pypy__ helper as the normalization rules are
	pretty annoying

diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py
--- a/lib_pypy/greenlet.py
+++ b/lib_pypy/greenlet.py
@@ -1,4 +1,5 @@
 import sys
+import __pypy__
 import _continuation
 
 __version__ = "0.4.0"
@@ -79,7 +80,7 @@
             # convert a "raise GreenletExit" into "return GreenletExit"
             if methodname == 'throw':
                 try:
-                    raise baseargs[0](baseargs[1])
+                    raise __pypy__.normalize_exc(baseargs[0], baseargs[1])
                 except GreenletExit as e:
                     methodname = 'switch'
                     baseargs = (((e,), {}),)
@@ -156,7 +157,7 @@
 def _greenlet_throw(greenlet, exc, value, tb):
     _tls.current = greenlet
     try:
-        raise value.with_traceback(tb)
+        raise __pypy__.normalize_exc(exc, value, tb)
     except GreenletExit as e:
         res = e
     finally:
diff --git a/pypy/module/__pypy__/__init__.py b/pypy/module/__pypy__/__init__.py
--- a/pypy/module/__pypy__/__init__.py
+++ b/pypy/module/__pypy__/__init__.py
@@ -74,6 +74,7 @@
         'newdict'                   : 'interp_dict.newdict',
         'dictstrategy'              : 'interp_dict.dictstrategy',
         'set_debug'                 : 'interp_magic.set_debug',
+        'normalize_exc'             : 'interp_magic.normalize_exc',
     }
 
     submodules = {
diff --git a/pypy/module/__pypy__/interp_magic.py b/pypy/module/__pypy__/interp_magic.py
--- a/pypy/module/__pypy__/interp_magic.py
+++ b/pypy/module/__pypy__/interp_magic.py
@@ -1,5 +1,5 @@
 from pypy.interpreter.error import OperationError, wrap_oserror
-from pypy.interpreter.gateway import unwrap_spec
+from pypy.interpreter.gateway import WrappedDefault, unwrap_spec
 from rpython.rlib.objectmodel import we_are_translated
 from pypy.objspace.std.listobject import W_ListObject
 from pypy.objspace.std.typeobject import MethodCache
@@ -108,3 +108,9 @@
 @unwrap_spec(estimate=int)
 def add_memory_pressure(estimate):
     rgc.add_memory_pressure(estimate)
+
+ at unwrap_spec(w_value=WrappedDefault(None), w_tb=WrappedDefault(None))
+def normalize_exc(space, w_type, w_value=None, w_tb=None):
+    operr = OperationError(w_type, w_value, w_tb)
+    operr.normalize_exception(space)
+    return operr.get_w_value(space)
diff --git a/pypy/module/__pypy__/test/test_special.py b/pypy/module/__pypy__/test/test_special.py
--- a/pypy/module/__pypy__/test/test_special.py
+++ b/pypy/module/__pypy__/test/test_special.py
@@ -93,6 +93,25 @@
         o = 5
         raises(TypeError, list_strategy, 5)
 
+    def test_normalize_exc(self):
+        from __pypy__ import normalize_exc
+        e = normalize_exc(TypeError)
+        assert isinstance(e, TypeError)
+        e = normalize_exc(TypeError, 'foo')
+        assert isinstance(e, TypeError)
+        assert str(e) == 'foo'
+        e = normalize_exc(TypeError('doh'))
+        assert isinstance(e, TypeError)
+        assert str(e) == 'doh'
+
+        try:
+            1 / 0
+        except ZeroDivisionError as e:
+            tb = e.__traceback__
+        e = normalize_exc(TypeError, None, tb)
+        assert isinstance(e, TypeError)
+        assert e.__traceback__ == tb
+
 
 class AppTestJitFeatures(object):
     spaceconfig = {"translation.jit": True}


More information about the pypy-commit mailing list