mirror of
https://github.com/python/cpython.git
synced 2025-10-13 18:33:34 +00:00
gh-99553: fix bug where an ExceptionGroup subclass can wrap a BaseException (GH-99572)
This commit is contained in:
parent
a220c6d1ee
commit
c8c6113398
4 changed files with 37 additions and 5 deletions
|
@ -965,6 +965,10 @@ their subgroups based on the types of the contained exceptions.
|
|||
def derive(self, excs):
|
||||
return Errors(excs, self.exit_code)
|
||||
|
||||
Like :exc:`ExceptionGroup`, any subclass of :exc:`BaseExceptionGroup` which
|
||||
is also a subclass of :exc:`Exception` can only wrap instances of
|
||||
:exc:`Exception`.
|
||||
|
||||
.. versionadded:: 3.11
|
||||
|
||||
|
||||
|
|
|
@ -78,16 +78,30 @@ class InstanceCreation(unittest.TestCase):
|
|||
beg = BaseExceptionGroup("beg", [ValueError(1), KeyboardInterrupt(2)])
|
||||
self.assertIs(type(beg), BaseExceptionGroup)
|
||||
|
||||
def test_EG_subclass_wraps_anything(self):
|
||||
def test_EG_subclass_wraps_non_base_exceptions(self):
|
||||
class MyEG(ExceptionGroup):
|
||||
pass
|
||||
|
||||
self.assertIs(
|
||||
type(MyEG("eg", [ValueError(12), TypeError(42)])),
|
||||
MyEG)
|
||||
self.assertIs(
|
||||
type(MyEG("eg", [ValueError(12), KeyboardInterrupt(42)])),
|
||||
MyEG)
|
||||
|
||||
def test_EG_subclass_does_not_wrap_base_exceptions(self):
|
||||
class MyEG(ExceptionGroup):
|
||||
pass
|
||||
|
||||
msg = "Cannot nest BaseExceptions in 'MyEG'"
|
||||
with self.assertRaisesRegex(TypeError, msg):
|
||||
MyEG("eg", [ValueError(12), KeyboardInterrupt(42)])
|
||||
|
||||
def test_BEG_and_E_subclass_does_not_wrap_base_exceptions(self):
|
||||
class MyEG(BaseExceptionGroup, ValueError):
|
||||
pass
|
||||
|
||||
msg = "Cannot nest BaseExceptions in 'MyEG'"
|
||||
with self.assertRaisesRegex(TypeError, msg):
|
||||
MyEG("eg", [ValueError(12), KeyboardInterrupt(42)])
|
||||
|
||||
|
||||
def test_BEG_subclass_wraps_anything(self):
|
||||
class MyBEG(BaseExceptionGroup):
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Fix bug where an :exc:`ExceptionGroup` subclass can wrap a
|
||||
:exc:`BaseException`.
|
|
@ -753,7 +753,19 @@ BaseExceptionGroup_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
|
|||
}
|
||||
}
|
||||
else {
|
||||
/* Do nothing - we don't interfere with subclasses */
|
||||
/* user-defined subclass */
|
||||
if (nested_base_exceptions) {
|
||||
int nonbase = PyObject_IsSubclass((PyObject*)cls, PyExc_Exception);
|
||||
if (nonbase == -1) {
|
||||
goto error;
|
||||
}
|
||||
else if (nonbase == 1) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"Cannot nest BaseExceptions in '%.200s'",
|
||||
cls->tp_name);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cls) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue