[Python-checkins] gh-103590: do not wrap a single exception raised from a try-except* (#103665)

iritkatriel webhook-mailer at python.org
Thu Apr 27 07:52:22 EDT 2023


https://github.com/python/cpython/commit/63842bd90793c693f56bd8aad710b5267d41cf6d
commit: 63842bd90793c693f56bd8aad710b5267d41cf6d
branch: main
author: Irit Katriel <1055913+iritkatriel at users.noreply.github.com>
committer: iritkatriel <1055913+iritkatriel at users.noreply.github.com>
date: 2023-04-27T12:52:15+01:00
summary:

gh-103590: do not wrap a single exception raised from a try-except* (#103665)

files:
A Misc/NEWS.d/next/Core and Builtins/2023-04-21-16-12-41.gh-issue-103590.7DHDOE.rst
M Doc/whatsnew/3.12.rst
M Lib/test/test_except_star.py
M Objects/exceptions.c

diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index ff631ab54e16..291500532493 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -237,6 +237,11 @@ Other Language Changes
   wrapped by a :exc:`RuntimeError`. Context information is added to the
   exception as a :pep:`678` note. (Contributed by Irit Katriel in :gh:`77757`.)
 
+* When a ``try-except*`` construct handles the entire :exc:`ExceptionGroup`
+  and raises one other exception, that exception is no longer wrapped in an
+  :exc:`ExceptionGroup`. (Contributed by Irit Katriel in :gh:`103590`.)
+
+
 New Modules
 ===========
 
diff --git a/Lib/test/test_except_star.py b/Lib/test/test_except_star.py
index bc66f90b9cad..c49c6008e08e 100644
--- a/Lib/test/test_except_star.py
+++ b/Lib/test/test_except_star.py
@@ -618,18 +618,17 @@ def test_raise_handle_all_raise_one_named(self):
                 raise orig
             except* (TypeError, ValueError) as e:
                 raise SyntaxError(3)
-        except BaseException as e:
+        except SyntaxError as e:
             exc = e
 
-        self.assertExceptionIsLike(
-            exc, ExceptionGroup("", [SyntaxError(3)]))
+        self.assertExceptionIsLike(exc, SyntaxError(3))
 
         self.assertExceptionIsLike(
-            exc.exceptions[0].__context__,
+            exc.__context__,
             ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
 
         self.assertMetadataNotEqual(orig, exc)
-        self.assertMetadataEqual(orig, exc.exceptions[0].__context__)
+        self.assertMetadataEqual(orig, exc.__context__)
 
     def test_raise_handle_all_raise_one_unnamed(self):
         orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
@@ -638,18 +637,17 @@ def test_raise_handle_all_raise_one_unnamed(self):
                 raise orig
             except* (TypeError, ValueError) as e:
                 raise SyntaxError(3)
-        except ExceptionGroup as e:
+        except SyntaxError as e:
             exc = e
 
-        self.assertExceptionIsLike(
-            exc, ExceptionGroup("", [SyntaxError(3)]))
+        self.assertExceptionIsLike(exc, SyntaxError(3))
 
         self.assertExceptionIsLike(
-            exc.exceptions[0].__context__,
+            exc.__context__,
             ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
 
         self.assertMetadataNotEqual(orig, exc)
-        self.assertMetadataEqual(orig, exc.exceptions[0].__context__)
+        self.assertMetadataEqual(orig, exc.__context__)
 
     def test_raise_handle_all_raise_two_named(self):
         orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
@@ -773,23 +771,22 @@ def test_raise_handle_all_raise_one_named(self):
                 raise orig
             except* (TypeError, ValueError) as e:
                 raise SyntaxError(3) from e
-        except BaseException as e:
+        except SyntaxError as e:
             exc = e
 
-        self.assertExceptionIsLike(
-            exc, ExceptionGroup("", [SyntaxError(3)]))
+        self.assertExceptionIsLike(exc, SyntaxError(3))
 
         self.assertExceptionIsLike(
-            exc.exceptions[0].__context__,
+            exc.__context__,
             ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
 
         self.assertExceptionIsLike(
-            exc.exceptions[0].__cause__,
+            exc.__cause__,
             ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
 
         self.assertMetadataNotEqual(orig, exc)
-        self.assertMetadataEqual(orig, exc.exceptions[0].__context__)
-        self.assertMetadataEqual(orig, exc.exceptions[0].__cause__)
+        self.assertMetadataEqual(orig, exc.__context__)
+        self.assertMetadataEqual(orig, exc.__cause__)
 
     def test_raise_handle_all_raise_one_unnamed(self):
         orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
@@ -799,23 +796,22 @@ def test_raise_handle_all_raise_one_unnamed(self):
             except* (TypeError, ValueError) as e:
                 e = sys.exception()
                 raise SyntaxError(3) from e
-        except ExceptionGroup as e:
+        except SyntaxError as e:
             exc = e
 
-        self.assertExceptionIsLike(
-            exc, ExceptionGroup("", [SyntaxError(3)]))
+        self.assertExceptionIsLike(exc, SyntaxError(3))
 
         self.assertExceptionIsLike(
-            exc.exceptions[0].__context__,
+            exc.__context__,
             ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
 
         self.assertExceptionIsLike(
-            exc.exceptions[0].__cause__,
+            exc.__cause__,
             ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
 
         self.assertMetadataNotEqual(orig, exc)
-        self.assertMetadataEqual(orig, exc.exceptions[0].__context__)
-        self.assertMetadataEqual(orig, exc.exceptions[0].__cause__)
+        self.assertMetadataEqual(orig, exc.__context__)
+        self.assertMetadataEqual(orig, exc.__cause__)
 
     def test_raise_handle_all_raise_two_named(self):
         orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-04-21-16-12-41.gh-issue-103590.7DHDOE.rst b/Misc/NEWS.d/next/Core and Builtins/2023-04-21-16-12-41.gh-issue-103590.7DHDOE.rst
new file mode 100644
index 000000000000..af733a8207a2
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-04-21-16-12-41.gh-issue-103590.7DHDOE.rst	
@@ -0,0 +1 @@
+Do not wrap a single exception raised from a ``try-except*`` construct in an :exc:`ExceptionGroup`.
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index a355244cf997..55a6768a3aac 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -1421,7 +1421,12 @@ _PyExc_PrepReraiseStar(PyObject *orig, PyObject *excs)
         if (res < 0) {
             goto done;
         }
-        result = _PyExc_CreateExceptionGroup("", raised_list);
+        if (PyList_GET_SIZE(raised_list) > 1) {
+            result = _PyExc_CreateExceptionGroup("", raised_list);
+        }
+        else {
+            result = Py_NewRef(PyList_GetItem(raised_list, 0));
+        }
         if (result == NULL) {
             goto done;
         }



More information about the Python-checkins mailing list