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

This commit is contained in:
Irit Katriel 2023-04-27 12:52:15 +01:00 committed by GitHub
parent 78942ecd9b
commit 63842bd907
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 32 additions and 25 deletions

View file

@ -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
===========

View file

@ -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)])

View file

@ -0,0 +1 @@
Do not wrap a single exception raised from a ``try-except*`` construct in an :exc:`ExceptionGroup`.

View file

@ -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;
}