Skip to content

Commit 63842bd

Browse files
authoredApr 27, 2023
gh-103590: do not wrap a single exception raised from a try-except* (#103665)
1 parent 78942ec commit 63842bd

File tree

4 files changed

+32
-25
lines changed

4 files changed

+32
-25
lines changed
 

‎Doc/whatsnew/3.12.rst

+5
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,11 @@ Other Language Changes
237237
wrapped by a :exc:`RuntimeError`. Context information is added to the
238238
exception as a :pep:`678` note. (Contributed by Irit Katriel in :gh:`77757`.)
239239

240+
* When a ``try-except*`` construct handles the entire :exc:`ExceptionGroup`
241+
and raises one other exception, that exception is no longer wrapped in an
242+
:exc:`ExceptionGroup`. (Contributed by Irit Katriel in :gh:`103590`.)
243+
244+
240245
New Modules
241246
===========
242247

‎Lib/test/test_except_star.py

+20-24
Original file line numberDiff line numberDiff line change
@@ -618,18 +618,17 @@ def test_raise_handle_all_raise_one_named(self):
618618
raise orig
619619
except* (TypeError, ValueError) as e:
620620
raise SyntaxError(3)
621-
except BaseException as e:
621+
except SyntaxError as e:
622622
exc = e
623623

624-
self.assertExceptionIsLike(
625-
exc, ExceptionGroup("", [SyntaxError(3)]))
624+
self.assertExceptionIsLike(exc, SyntaxError(3))
626625

627626
self.assertExceptionIsLike(
628-
exc.exceptions[0].__context__,
627+
exc.__context__,
629628
ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
630629

631630
self.assertMetadataNotEqual(orig, exc)
632-
self.assertMetadataEqual(orig, exc.exceptions[0].__context__)
631+
self.assertMetadataEqual(orig, exc.__context__)
633632

634633
def test_raise_handle_all_raise_one_unnamed(self):
635634
orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
@@ -638,18 +637,17 @@ def test_raise_handle_all_raise_one_unnamed(self):
638637
raise orig
639638
except* (TypeError, ValueError) as e:
640639
raise SyntaxError(3)
641-
except ExceptionGroup as e:
640+
except SyntaxError as e:
642641
exc = e
643642

644-
self.assertExceptionIsLike(
645-
exc, ExceptionGroup("", [SyntaxError(3)]))
643+
self.assertExceptionIsLike(exc, SyntaxError(3))
646644

647645
self.assertExceptionIsLike(
648-
exc.exceptions[0].__context__,
646+
exc.__context__,
649647
ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
650648

651649
self.assertMetadataNotEqual(orig, exc)
652-
self.assertMetadataEqual(orig, exc.exceptions[0].__context__)
650+
self.assertMetadataEqual(orig, exc.__context__)
653651

654652
def test_raise_handle_all_raise_two_named(self):
655653
orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
@@ -773,23 +771,22 @@ def test_raise_handle_all_raise_one_named(self):
773771
raise orig
774772
except* (TypeError, ValueError) as e:
775773
raise SyntaxError(3) from e
776-
except BaseException as e:
774+
except SyntaxError as e:
777775
exc = e
778776

779-
self.assertExceptionIsLike(
780-
exc, ExceptionGroup("", [SyntaxError(3)]))
777+
self.assertExceptionIsLike(exc, SyntaxError(3))
781778

782779
self.assertExceptionIsLike(
783-
exc.exceptions[0].__context__,
780+
exc.__context__,
784781
ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
785782

786783
self.assertExceptionIsLike(
787-
exc.exceptions[0].__cause__,
784+
exc.__cause__,
788785
ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
789786

790787
self.assertMetadataNotEqual(orig, exc)
791-
self.assertMetadataEqual(orig, exc.exceptions[0].__context__)
792-
self.assertMetadataEqual(orig, exc.exceptions[0].__cause__)
788+
self.assertMetadataEqual(orig, exc.__context__)
789+
self.assertMetadataEqual(orig, exc.__cause__)
793790

794791
def test_raise_handle_all_raise_one_unnamed(self):
795792
orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
@@ -799,23 +796,22 @@ def test_raise_handle_all_raise_one_unnamed(self):
799796
except* (TypeError, ValueError) as e:
800797
e = sys.exception()
801798
raise SyntaxError(3) from e
802-
except ExceptionGroup as e:
799+
except SyntaxError as e:
803800
exc = e
804801

805-
self.assertExceptionIsLike(
806-
exc, ExceptionGroup("", [SyntaxError(3)]))
802+
self.assertExceptionIsLike(exc, SyntaxError(3))
807803

808804
self.assertExceptionIsLike(
809-
exc.exceptions[0].__context__,
805+
exc.__context__,
810806
ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
811807

812808
self.assertExceptionIsLike(
813-
exc.exceptions[0].__cause__,
809+
exc.__cause__,
814810
ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
815811

816812
self.assertMetadataNotEqual(orig, exc)
817-
self.assertMetadataEqual(orig, exc.exceptions[0].__context__)
818-
self.assertMetadataEqual(orig, exc.exceptions[0].__cause__)
813+
self.assertMetadataEqual(orig, exc.__context__)
814+
self.assertMetadataEqual(orig, exc.__cause__)
819815

820816
def test_raise_handle_all_raise_two_named(self):
821817
orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Do not wrap a single exception raised from a ``try-except*`` construct in an :exc:`ExceptionGroup`.

‎Objects/exceptions.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -1421,7 +1421,12 @@ _PyExc_PrepReraiseStar(PyObject *orig, PyObject *excs)
14211421
if (res < 0) {
14221422
goto done;
14231423
}
1424-
result = _PyExc_CreateExceptionGroup("", raised_list);
1424+
if (PyList_GET_SIZE(raised_list) > 1) {
1425+
result = _PyExc_CreateExceptionGroup("", raised_list);
1426+
}
1427+
else {
1428+
result = Py_NewRef(PyList_GetItem(raised_list, 0));
1429+
}
14251430
if (result == NULL) {
14261431
goto done;
14271432
}

0 commit comments

Comments
 (0)
Please sign in to comment.