mirror of https://github.com/python/cpython
gh-103590: do not wrap a single exception raised from a try-except* (#103665)
This commit is contained in:
parent
78942ecd9b
commit
63842bd907
|
@ -237,6 +237,11 @@ Other Language Changes
|
||||||
wrapped by a :exc:`RuntimeError`. Context information is added to the
|
wrapped by a :exc:`RuntimeError`. Context information is added to the
|
||||||
exception as a :pep:`678` note. (Contributed by Irit Katriel in :gh:`77757`.)
|
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
|
New Modules
|
||||||
===========
|
===========
|
||||||
|
|
||||||
|
|
|
@ -618,18 +618,17 @@ class TestExceptStarRaise(ExceptStarTest):
|
||||||
raise orig
|
raise orig
|
||||||
except* (TypeError, ValueError) as e:
|
except* (TypeError, ValueError) as e:
|
||||||
raise SyntaxError(3)
|
raise SyntaxError(3)
|
||||||
except BaseException as e:
|
except SyntaxError as e:
|
||||||
exc = e
|
exc = e
|
||||||
|
|
||||||
self.assertExceptionIsLike(
|
self.assertExceptionIsLike(exc, SyntaxError(3))
|
||||||
exc, ExceptionGroup("", [SyntaxError(3)]))
|
|
||||||
|
|
||||||
self.assertExceptionIsLike(
|
self.assertExceptionIsLike(
|
||||||
exc.exceptions[0].__context__,
|
exc.__context__,
|
||||||
ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
|
ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
|
||||||
|
|
||||||
self.assertMetadataNotEqual(orig, exc)
|
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):
|
def test_raise_handle_all_raise_one_unnamed(self):
|
||||||
orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
|
orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
|
||||||
|
@ -638,18 +637,17 @@ class TestExceptStarRaise(ExceptStarTest):
|
||||||
raise orig
|
raise orig
|
||||||
except* (TypeError, ValueError) as e:
|
except* (TypeError, ValueError) as e:
|
||||||
raise SyntaxError(3)
|
raise SyntaxError(3)
|
||||||
except ExceptionGroup as e:
|
except SyntaxError as e:
|
||||||
exc = e
|
exc = e
|
||||||
|
|
||||||
self.assertExceptionIsLike(
|
self.assertExceptionIsLike(exc, SyntaxError(3))
|
||||||
exc, ExceptionGroup("", [SyntaxError(3)]))
|
|
||||||
|
|
||||||
self.assertExceptionIsLike(
|
self.assertExceptionIsLike(
|
||||||
exc.exceptions[0].__context__,
|
exc.__context__,
|
||||||
ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
|
ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
|
||||||
|
|
||||||
self.assertMetadataNotEqual(orig, exc)
|
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):
|
def test_raise_handle_all_raise_two_named(self):
|
||||||
orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
|
orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
|
||||||
|
@ -773,23 +771,22 @@ class TestExceptStarRaiseFrom(ExceptStarTest):
|
||||||
raise orig
|
raise orig
|
||||||
except* (TypeError, ValueError) as e:
|
except* (TypeError, ValueError) as e:
|
||||||
raise SyntaxError(3) from e
|
raise SyntaxError(3) from e
|
||||||
except BaseException as e:
|
except SyntaxError as e:
|
||||||
exc = e
|
exc = e
|
||||||
|
|
||||||
self.assertExceptionIsLike(
|
self.assertExceptionIsLike(exc, SyntaxError(3))
|
||||||
exc, ExceptionGroup("", [SyntaxError(3)]))
|
|
||||||
|
|
||||||
self.assertExceptionIsLike(
|
self.assertExceptionIsLike(
|
||||||
exc.exceptions[0].__context__,
|
exc.__context__,
|
||||||
ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
|
ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
|
||||||
|
|
||||||
self.assertExceptionIsLike(
|
self.assertExceptionIsLike(
|
||||||
exc.exceptions[0].__cause__,
|
exc.__cause__,
|
||||||
ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
|
ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
|
||||||
|
|
||||||
self.assertMetadataNotEqual(orig, exc)
|
self.assertMetadataNotEqual(orig, exc)
|
||||||
self.assertMetadataEqual(orig, exc.exceptions[0].__context__)
|
self.assertMetadataEqual(orig, exc.__context__)
|
||||||
self.assertMetadataEqual(orig, exc.exceptions[0].__cause__)
|
self.assertMetadataEqual(orig, exc.__cause__)
|
||||||
|
|
||||||
def test_raise_handle_all_raise_one_unnamed(self):
|
def test_raise_handle_all_raise_one_unnamed(self):
|
||||||
orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
|
orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
|
||||||
|
@ -799,23 +796,22 @@ class TestExceptStarRaiseFrom(ExceptStarTest):
|
||||||
except* (TypeError, ValueError) as e:
|
except* (TypeError, ValueError) as e:
|
||||||
e = sys.exception()
|
e = sys.exception()
|
||||||
raise SyntaxError(3) from e
|
raise SyntaxError(3) from e
|
||||||
except ExceptionGroup as e:
|
except SyntaxError as e:
|
||||||
exc = e
|
exc = e
|
||||||
|
|
||||||
self.assertExceptionIsLike(
|
self.assertExceptionIsLike(exc, SyntaxError(3))
|
||||||
exc, ExceptionGroup("", [SyntaxError(3)]))
|
|
||||||
|
|
||||||
self.assertExceptionIsLike(
|
self.assertExceptionIsLike(
|
||||||
exc.exceptions[0].__context__,
|
exc.__context__,
|
||||||
ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
|
ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
|
||||||
|
|
||||||
self.assertExceptionIsLike(
|
self.assertExceptionIsLike(
|
||||||
exc.exceptions[0].__cause__,
|
exc.__cause__,
|
||||||
ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
|
ExceptionGroup("eg", [TypeError(1), ValueError(2)]))
|
||||||
|
|
||||||
self.assertMetadataNotEqual(orig, exc)
|
self.assertMetadataNotEqual(orig, exc)
|
||||||
self.assertMetadataEqual(orig, exc.exceptions[0].__context__)
|
self.assertMetadataEqual(orig, exc.__context__)
|
||||||
self.assertMetadataEqual(orig, exc.exceptions[0].__cause__)
|
self.assertMetadataEqual(orig, exc.__cause__)
|
||||||
|
|
||||||
def test_raise_handle_all_raise_two_named(self):
|
def test_raise_handle_all_raise_two_named(self):
|
||||||
orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
|
orig = ExceptionGroup("eg", [TypeError(1), ValueError(2)])
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Do not wrap a single exception raised from a ``try-except*`` construct in an :exc:`ExceptionGroup`.
|
|
@ -1421,7 +1421,12 @@ _PyExc_PrepReraiseStar(PyObject *orig, PyObject *excs)
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
goto done;
|
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) {
|
if (result == NULL) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue