[pypy-commit] pypy py3.6: fix error handling in __set_name__

cfbolz pypy.commits at gmail.com
Fri May 11 08:17:31 EDT 2018


Author: Carl Friedrich Bolz-Tereick <cfbolz at gmx.de>
Branch: py3.6
Changeset: r94523:787eff4a164e
Date: 2018-05-11 14:16 +0200
http://bitbucket.org/pypy/pypy/changeset/787eff4a164e/

Log:	fix error handling in __set_name__

diff --git a/pypy/objspace/std/test/test_typeobject.py b/pypy/objspace/std/test/test_typeobject.py
--- a/pypy/objspace/std/test/test_typeobject.py
+++ b/pypy/objspace/std/test/test_typeobject.py
@@ -1556,6 +1556,17 @@
         assert X.a.owner is X
         assert X.a.name == "a"
 
+    def test_set_name_error(self):
+        class Descriptor:
+            __set_name__ = None
+        def make_class():
+            class A:
+                d = Descriptor()
+        excinfo = raises(RuntimeError, make_class)
+        assert isinstance(excinfo.value.__cause__, TypeError)
+        assert str(excinfo.value) == "Error calling __set_name__ on 'Descriptor' instance 'd' in 'A'"
+        print(excinfo.value)
+
     def test_type_init_accepts_kwargs(self):
         type.__init__(type, "a", (object, ), {}, a=1)
 
diff --git a/pypy/objspace/std/typeobject.py b/pypy/objspace/std/typeobject.py
--- a/pypy/objspace/std/typeobject.py
+++ b/pypy/objspace/std/typeobject.py
@@ -835,8 +835,14 @@
     for key, w_value in w_type.dict_w.iteritems():
         w_meth = space.lookup(w_value, '__set_name__')
         if w_meth is not None:
-            # XXX what happens when the call raises, gets turned into a RuntimeError?
-            space.get_and_call_function(w_meth, w_value, w_type, space.newtext(key))
+            try:
+                space.get_and_call_function(w_meth, w_value, w_type, space.newtext(key))
+            except OperationError as e:
+                e2 = oefmt(space.w_RuntimeError,
+                           "Error calling __set_name__ on '%T' instance '%s' in '%N'",
+                           w_value, key, w_type)
+                e2.chain_exceptions_from_cause(space, e)
+                raise e2
 
 def _init_subclass(space, w_type, __args__):
     # bit of a mess, but I didn't feel like implementing the super logic


More information about the pypy-commit mailing list