Commits

Philip Jenvey committed 6a0b8e7

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

  • Participants
  • Parent commits ffec732
  • Branches py3k

Comments (0)

Files changed (4)

lib_pypy/greenlet.py

 import sys
+import __pypy__
 import _continuation
 
 __version__ = "0.4.0"
             # 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,), {}),)
 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:

pypy/module/__pypy__/__init__.py

         'newdict'                   : 'interp_dict.newdict',
         'dictstrategy'              : 'interp_dict.dictstrategy',
         'set_debug'                 : 'interp_magic.set_debug',
+        'normalize_exc'             : 'interp_magic.normalize_exc',
     }
 
     submodules = {

pypy/module/__pypy__/interp_magic.py

 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
 @unwrap_spec(estimate=int)
 def add_memory_pressure(estimate):
     rgc.add_memory_pressure(estimate)
+
+@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)

pypy/module/__pypy__/test/test_special.py

         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}