]> granicus.if.org Git - python/commitdiff
Issue #28214: Improved exception reporting for problematic __set_name__
authorSerhiy Storchaka <storchaka@gmail.com>
Fri, 21 Oct 2016 14:13:31 +0000 (17:13 +0300)
committerSerhiy Storchaka <storchaka@gmail.com>
Fri, 21 Oct 2016 14:13:31 +0000 (17:13 +0300)
attributes.

Lib/test/test_subclassinit.py
Misc/NEWS
Objects/typeobject.c

index 0267e417177536ee2ad038a1b1debd50f745059a..6a12fb1ee0f83d7aa24e9342ab00376225e64ffd 100644 (file)
@@ -133,20 +133,32 @@ class Test(unittest.TestCase):
     def test_set_name_error(self):
         class Descriptor:
             def __set_name__(self, owner, name):
-                raise RuntimeError
+                1/0
 
-        with self.assertRaises(RuntimeError):
-            class A:
-                d = Descriptor()
+        with self.assertRaises(RuntimeError) as cm:
+            class NotGoingToWork:
+                attr = Descriptor()
+
+        exc = cm.exception
+        self.assertRegex(str(exc), r'\bNotGoingToWork\b')
+        self.assertRegex(str(exc), r'\battr\b')
+        self.assertRegex(str(exc), r'\bDescriptor\b')
+        self.assertIsInstance(exc.__cause__, ZeroDivisionError)
 
     def test_set_name_wrong(self):
         class Descriptor:
             def __set_name__(self):
                 pass
 
-        with self.assertRaises(TypeError):
-            class A:
-                d = Descriptor()
+        with self.assertRaises(RuntimeError) as cm:
+            class NotGoingToWork:
+                attr = Descriptor()
+
+        exc = cm.exception
+        self.assertRegex(str(exc), r'\bNotGoingToWork\b')
+        self.assertRegex(str(exc), r'\battr\b')
+        self.assertRegex(str(exc), r'\bDescriptor\b')
+        self.assertIsInstance(exc.__cause__, TypeError)
 
     def test_set_name_lookup(self):
         resolved = []
index 237c9288e6c93f01411f595c7a5396edf7adfab0..4410edadf9a5306d742a96e54e09c123d53f3a96 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.6.0 beta 3
 Core and Builtins
 -----------------
 
+- Issue #28214: Improved exception reporting for problematic __set_name__
+  attributes.
+
 - Issue #23782: Fixed possible memory leak in _PyTraceback_Add() and exception
   loss in PyTraceBack_Here().
 
index 1021a75308cb284488cef38c0eb3289524207b5a..bfbeb40d2c7bbddda155df98eb17a004b8ba9e8a 100644 (file)
@@ -7022,8 +7022,13 @@ set_names(PyTypeObject *type)
         if (set_name != NULL) {
             tmp = PyObject_CallFunctionObjArgs(set_name, type, key, NULL);
             Py_DECREF(set_name);
-            if (tmp == NULL)
+            if (tmp == NULL) {
+                _PyErr_FormatFromCause(PyExc_RuntimeError,
+                    "Error calling __set_name__ on '%.100s' instance %R "
+                    "in '%.100s'",
+                    value->ob_type->tp_name, key, type->tp_name);
                 return -1;
+            }
             else
                 Py_DECREF(tmp);
         }