| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -270,6 +270,32 @@ def gen(): | |||
| 270 | 270 | self.assertEqual(next(g), "done") | |
| 271 | 271 | self.assertEqual(sys.exc_info(), (None, None, None)) | |
| 272 | 272 | ||
| 273 | + def test_except_throw_bad_exception(self): | ||
| 274 | + class E(Exception): | ||
| 275 | + def __new__(cls, *args, **kwargs): | ||
| 276 | + return cls | ||
| 277 | + | ||
| 278 | + def boring_generator(): | ||
| 279 | + yield | ||
| 280 | + | ||
| 281 | + gen = boring_generator() | ||
| 282 | + | ||
| 283 | + err_msg = 'should have returned an instance of BaseException' | ||
| 284 | + | ||
| 285 | + with self.assertRaisesRegex(TypeError, err_msg): | ||
| 286 | + gen.throw(E) | ||
| 287 | + | ||
| 288 | + self.assertRaises(StopIteration, next, gen) | ||
| 289 | + | ||
| 290 | + def generator(): | ||
| 291 | + with self.assertRaisesRegex(TypeError, err_msg): | ||
| 292 | + yield | ||
| 293 | + | ||
| 294 | + gen = generator() | ||
| 295 | + next(gen) | ||
| 296 | + with self.assertRaises(StopIteration): | ||
| 297 | + gen.throw(E) | ||
| 298 | + | ||
| 273 | 299 | def test_stopiteration_error(self): | |
| 274 | 300 | # See also PEP 479. | |
| 275 | 301 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1300,6 +1300,7 @@ Peter Otten | |||
| 1300 | 1300 | Michael Otteneder | |
| 1301 | 1301 | Richard Oudkerk | |
| 1302 | 1302 | Russel Owen | |
| 1303 | + Noah Oxer | ||
| 1303 | 1304 | Joonas Paalasmaa | |
| 1304 | 1305 | Yaroslav Pankovych | |
| 1305 | 1306 | Martin Packman | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1 @@ | |||
| 1 | + Fix crash when using passing a non-exception to a generator's ``throw()`` method. Patch by Noah Oxer | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -85,17 +85,29 @@ _PyErr_GetTopmostException(PyThreadState *tstate) | |||
| 85 | 85 | } | |
| 86 | 86 | ||
| 87 | 87 | static PyObject* | |
| 88 | - _PyErr_CreateException(PyObject *exception, PyObject *value) | ||
| 88 | + _PyErr_CreateException(PyObject *exception_type, PyObject *value) | ||
| 89 | 89 | { | |
| 90 | + PyObject *exc; | ||
| 91 | + | ||
| 90 | 92 | if (value == NULL || value == Py_None) { | |
| 91 | - return _PyObject_CallNoArg(exception); | ||
| 93 | + exc = _PyObject_CallNoArg(exception_type); | ||
| 92 | 94 | } | |
| 93 | 95 | else if (PyTuple_Check(value)) { | |
| 94 | - return PyObject_Call(exception, value, NULL); | ||
| 96 | + exc = PyObject_Call(exception_type, value, NULL); | ||
| 95 | 97 | } | |
| 96 | 98 | else { | |
| 97 | - return PyObject_CallOneArg(exception, value); | ||
| 99 | + exc = PyObject_CallOneArg(exception_type, value); | ||
| 100 | + } | ||
| 101 | + | ||
| 102 | + if (exc != NULL && !PyExceptionInstance_Check(exc)) { | ||
| 103 | + PyErr_Format(PyExc_TypeError, | ||
| 104 | + "calling %R should have returned an instance of " | ||
| 105 | + "BaseException, not %s", | ||
| 106 | + exception_type, Py_TYPE(exc)->tp_name); | ||
| 107 | + Py_CLEAR(exc); | ||
| 98 | 108 | } | |
| 109 | + | ||
| 110 | + return exc; | ||
| 99 | 111 | } | |
| 100 | 112 | ||
| 101 | 113 | void | |
| Back | FazBrowse Home | New Git URL |
0 commit comments