Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 35.2k
gh-96348: Deprecate the 3-arg signature of coroutine.throw, generator.throw and agen.athrow#96428
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
b388f9a713d77afcfb65e073aa621c6ed30488185501588168152b7c670d8f80c20b35ba9a87c7f1dd7f0b16455e204cc60873dc34a1539c85b67cb22bb65b7b786e4198645a528031c53c74db93db9660e56eb9873827331b2e9f8b701d670e1f28ed2e83a03fc6e0File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -582,6 +582,11 @@ is already executing raises a :exc:`ValueError` exception. | ||
| :attr:`~BaseException.__traceback__` attribute stored in *value* may | ||
| be cleared. | ||
| .. versionchanged:: 3.12 | ||
| The second signature \(type\[, value\[, traceback\]\]\) is deprecated and | ||
| may be removed in a future version of Python. | ||
| .. index:: exception: GeneratorExit | ||
| @@ -738,7 +743,8 @@ which are used to control the execution of a generator function. | ||
| because there is no yield expression that could receive the value. | ||
| .. coroutinemethod:: agen.athrow(type[, value[, traceback]]) | ||
| .. coroutinemethod:: agen.athrow(value) | ||
| agen.athrow(type[, value[, traceback]]) | ||
| Returns an awaitable that raises an exception of type ``type`` at the point | ||
| where the asynchronous generator was paused, and returns the next value | ||
| @@ -750,6 +756,11 @@ which are used to control the execution of a generator function. | ||
| raises a different exception, then when the awaitable is run that exception | ||
| propagates to the caller of the awaitable. | ||
| .. versionchanged:: 3.12 | ||
| The second signature \(type\[, value\[, traceback\]\]\) is deprecated and | ||
| may be removed in a future version of Python. | ||
iritkatriel marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| .. index:: exception: GeneratorExit | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -2,6 +2,7 @@ | ||
| import types | ||
| import unittest | ||
| import contextlib | ||
| import warnings | ||
| from test.support.import_helper import import_module | ||
| from test.support import gc_collect, requires_working_socket | ||
| @@ -377,6 +378,13 @@ async def async_gen_wrapper(): | ||
| self.compare_generators(sync_gen_wrapper(), async_gen_wrapper()) | ||
| def test_async_gen_3_arg_deprecation_warning(self): | ||
| async def gen(): | ||
| yield 123 | ||
ofey404 marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| with self.assertWarns(DeprecationWarning): | ||
| gen().athrow(GeneratorExit, GeneratorExit(), None) | ||
| def test_async_gen_api_01(self): | ||
| async def gen(): | ||
| yield 123 | ||
| @@ -650,7 +658,7 @@ def test1(anext): | ||
| agen = agenfn() | ||
| with contextlib.closing(anext(agen, "default").__await__()) as g: | ||
| self.assertEqual(g.send(None), 1) | ||
| self.assertEqual(g.throw(MyError, MyError(), None), 2) | ||
| self.assertEqual(g.throw(MyError()), 2) | ||
| try: | ||
| g.send(None) | ||
| except StopIteration as e: | ||
| @@ -663,9 +671,9 @@ def test2(anext): | ||
| agen = agenfn() | ||
| with contextlib.closing(anext(agen, "default").__await__()) as g: | ||
| self.assertEqual(g.send(None), 1) | ||
| self.assertEqual(g.throw(MyError, MyError(), None), 2) | ||
| self.assertEqual(g.throw(MyError()), 2) | ||
| with self.assertRaises(MyError): | ||
| g.throw(MyError, MyError(), None) | ||
| g.throw(MyError()) | ||
| def test3(anext): | ||
| agen = agenfn() | ||
| @@ -692,9 +700,9 @@ async def agenfn(): | ||
| agen = agenfn() | ||
| with contextlib.closing(anext(agen, "default").__await__()) as g: | ||
| self.assertEqual(g.send(None), 10) | ||
| self.assertEqual(g.throw(MyError, MyError(), None), 20) | ||
| self.assertEqual(g.throw(MyError()), 20) | ||
| with self.assertRaisesRegex(MyError, 'val'): | ||
| g.throw(MyError, MyError('val'), None) | ||
| g.throw(MyError('val')) | ||
| def test5(anext): | ||
| @types.coroutine | ||
| @@ -713,7 +721,7 @@ async def agenfn(): | ||
| with contextlib.closing(anext(agen, "default").__await__()) as g: | ||
| self.assertEqual(g.send(None), 10) | ||
| with self.assertRaisesRegex(StopIteration, 'default'): | ||
| g.throw(MyError, MyError(), None) | ||
| g.throw(MyError()) | ||
| def test6(anext): | ||
| @types.coroutine | ||
| @@ -728,7 +736,7 @@ async def agenfn(): | ||
| agen = agenfn() | ||
| with contextlib.closing(anext(agen, "default").__await__()) as g: | ||
| with self.assertRaises(MyError): | ||
| g.throw(MyError, MyError(), None) | ||
| g.throw(MyError()) | ||
| def run_test(test): | ||
| with self.subTest('pure-Python anext()'): | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| Emit a DeprecationWarning when :meth:`~generator.throw`, :meth:`~coroutine.throw` or :meth:`~agen.athrow` | ||
| are called with more than one argument. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -418,7 +418,9 @@ PyDoc_STRVAR(throw_doc, | ||
| throw(type[,value[,tb]])\n\ | ||
| \n\ | ||
| Raise exception in generator, return next yielded value or raise\n\ | ||
| StopIteration."); | ||
| StopIteration.\n\ | ||
| the (type, val, tb) signature is deprecated, \n\ | ||
| and may be removed in a future version of Python."); | ||
iritkatriel marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| static PyObject * | ||
| _gen_throw(PyGenObject *gen, int close_on_genexit, | ||
| @@ -559,6 +561,14 @@ gen_throw(PyGenObject *gen, PyObject *const *args, Py_ssize_t nargs) | ||
| if (!_PyArg_CheckPositional("throw", nargs, 1, 3)) { | ||
| return NULL; | ||
| } | ||
| if (nargs > 1) { | ||
| if (PyErr_WarnEx(PyExc_DeprecationWarning, | ||
| "the (type, exc, tb) signature of throw() is deprecated, " | ||
| "use the single-arg signature instead.", | ||
| 1) < 0) { | ||
| return NULL; | ||
| } | ||
| } | ||
| typ = args[0]; | ||
| if (nargs == 3) { | ||
| val = args[1]; | ||
| @@ -1147,7 +1157,10 @@ PyDoc_STRVAR(coro_throw_doc, | ||
| throw(type[,value[,traceback]])\n\ | ||
| \n\ | ||
| Raise exception in coroutine, return next iterated value or raise\n\ | ||
| StopIteration."); | ||
| StopIteration.\n\ | ||
| the (type, val, tb) signature is deprecated, \n\ | ||
| and may be removed in a future version of Python."); | ||
| PyDoc_STRVAR(coro_close_doc, | ||
| "close() -> raise GeneratorExit inside coroutine."); | ||
| @@ -1500,6 +1513,14 @@ async_gen_aclose(PyAsyncGenObject *o, PyObject *arg) | ||
| static PyObject * | ||
| async_gen_athrow(PyAsyncGenObject *o, PyObject *args) | ||
| { | ||
| if (PyTuple_GET_SIZE(args) > 1) { | ||
| if (PyErr_WarnEx(PyExc_DeprecationWarning, | ||
| "the (type, exc, tb) signature of athrow() is deprecated, " | ||
| "use the single-arg signature instead.", | ||
| 1) < 0) { | ||
| return NULL; | ||
| } | ||
| } | ||
| if (async_gen_init_hooks(o)) { | ||
| return NULL; | ||
| } | ||
| @@ -1537,7 +1558,12 @@ PyDoc_STRVAR(async_asend_doc, | ||
| "asend(v) -> send 'v' in generator."); | ||
| PyDoc_STRVAR(async_athrow_doc, | ||
| "athrow(typ[,val[,tb]]) -> raise exception in generator."); | ||
| "athrow(value)\n\ | ||
| athrow(type[,value[,tb]])\n\ | ||
| \n\ | ||
| raise exception in generator.\n\ | ||
| the (type, val, tb) signature is deprecated, \n\ | ||
| and may be removed in a future version of Python."); | ||
| static PyMethodDef async_gen_methods[] = { | ||
| {"asend", (PyCFunction)async_gen_asend, METH_O, async_asend_doc}, | ||
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For future PRs, not that code should generally be marked up like