Skip to content
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

gh-96348: Deprecate the 3-arg signature of coroutine.throw, generator.throw and agen.athrow #96428

Merged
merged 30 commits into from
Sep 30, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b388f9a
feat: Deprecate gen.throw(typ, val, tb)
ofey404 Aug 30, 2022
713d77a
Update Objects/genobject.c
ofey404 Aug 31, 2022
fcfb65e
fix clear cases
ofey404 Sep 1, 2022
073aa62
Update Misc/NEWS.d/next/Core and Builtins/2022-08-31-18-46-13.gh-issu…
ofey404 Sep 3, 2022
1c6ed30
Filter remaining warnings.
ofey404 Sep 3, 2022
4881855
Add deprecated info in documentation.
ofey404 Sep 6, 2022
0158816
Use versionchanged instead of deprecated.
ofey404 Sep 7, 2022
8152b7c
Update Doc/reference/expressions.rst
ofey404 Sep 9, 2022
670d8f8
more docs and what's new entry
ofey404 Sep 9, 2022
0c20b35
Edit what's new.
ofey404 Sep 10, 2022
ba9a87c
Update Objects/genobject.c
ofey404 Sep 13, 2022
7f1dd7f
Update Objects/genobject.c
ofey404 Sep 13, 2022
0b16455
Update Lib/test/test_generators.py
ofey404 Sep 13, 2022
e204cc6
Update Objects/genobject.c
ofey404 Sep 13, 2022
0873dc3
Reversed agen.athrow() documentation, and what's new with method link.
ofey404 Sep 20, 2022
4a1539c
Apply suggestions from code review
ofey404 Sep 22, 2022
85b67cb
Add DeprecationWarning, doc and what's new to agen.athrow
ofey404 Sep 22, 2022
22bb65b
Update acks, and doc of anextawaitable_throw
ofey404 Sep 22, 2022
7b786e4
Add test_async_gen_3_arg_deprecation_warning.
ofey404 Sep 24, 2022
198645a
Apply formatting suggestions from code review
ofey404 Sep 25, 2022
528031c
patchcheck.py passed
ofey404 Sep 25, 2022
53c74db
Merge branch 'main' into ofey404/deprecate-get-throw
ofey404 Sep 25, 2022
93db966
Update Misc/NEWS.d/next/Core and Builtins/2022-08-31-18-46-13.gh-issu…
ofey404 Sep 25, 2022
0e56eb9
assert that deprecation warning is emitted
iritkatriel Sep 25, 2022
8738273
stage, exploring how to capture deprecation warning rather than supre…
ofey404 Sep 28, 2022
31b2e9f
Revert "stage, exploring how to capture deprecation warning rather th…
ofey404 Sep 28, 2022
8b701d6
Merge pull request #6 from iritkatriel/pr96428
ofey404 Sep 28, 2022
70e1f28
Merge branch 'main' into ofey404/deprecate-get-throw
iritkatriel Sep 28, 2022
ed2e83a
fix test
iritkatriel Sep 28, 2022
03fc6e0
Add a warning in FutureIter_throw
ofey404 Sep 29, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Lib/contextlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ def __exit__(self, typ, value, traceback):
# tell if we get the same exception back
value = typ()
try:
self.gen.throw(typ, value, traceback)
self.gen.throw(value)
except StopIteration as exc:
# Suppress StopIteration *unless* it's the same exception that
# was passed to throw(). This prevents a StopIteration
Expand Down Expand Up @@ -219,7 +219,7 @@ async def __aexit__(self, typ, value, traceback):
# tell if we get the same exception back
value = typ()
try:
await self.gen.athrow(typ, value, traceback)
await self.gen.athrow(value)
except StopAsyncIteration as exc:
# Suppress StopIteration *unless* it's the same exception that
# was passed to throw(). This prevents a StopIteration
Expand Down
14 changes: 7 additions & 7 deletions Lib/test/test_asyncgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,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:
Expand All @@ -663,9 +663,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()
Expand All @@ -692,9 +692,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
Expand All @@ -713,7 +713,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
Expand All @@ -728,7 +728,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()'):
Expand Down
11 changes: 7 additions & 4 deletions Lib/test/test_asyncio/test_futures.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from types import GenericAlias
import asyncio
from asyncio import futures
import warnings
from test.test_asyncio import utils as test_utils
from test import support

Expand Down Expand Up @@ -619,10 +620,12 @@ def test_future_stop_iteration_args(self):
def test_future_iter_throw(self):
fut = self._new_future(loop=self.loop)
fi = iter(fut)
self.assertRaises(TypeError, fi.throw,
Exception, Exception("elephant"), 32)
self.assertRaises(TypeError, fi.throw,
Exception("elephant"), Exception("elephant"))
with warnings.catch_warnings():
warnings.filterwarnings("ignore", category=DeprecationWarning)
self.assertRaises(TypeError, fi.throw,
Exception, Exception("elephant"), 32)
self.assertRaises(TypeError, fi.throw,
Exception("elephant"), Exception("elephant"))
self.assertRaises(TypeError, fi.throw, list)

def test_future_del_collect(self):
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_coroutines.py
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,7 @@ async def foo():
aw = coro.__await__()
next(aw)
with self.assertRaises(ZeroDivisionError):
aw.throw(ZeroDivisionError, None, None)
aw.throw(ZeroDivisionError())
self.assertEqual(N, 102)

def test_func_11(self):
Expand Down
13 changes: 13 additions & 0 deletions Lib/test/test_generators.py
Original file line number Diff line number Diff line change
Expand Up @@ -2113,6 +2113,13 @@ def printsolution(self, x):
>>> g.throw(ValueError("xyz")) # value only
caught ValueError (xyz)

>>> import warnings
>>> warnings.filterwarnings("ignore", category=DeprecationWarning)

# Filter DeprecationWarning: the (type, val, tb) exception representation is deprecated,
# and may be removed in a future version of Python.
# Will re-enable it soon.
ofey404 marked this conversation as resolved.
Show resolved Hide resolved

>>> g.throw(ValueError, ValueError(1)) # value+matching type
caught ValueError (1)

Expand Down Expand Up @@ -2181,6 +2188,12 @@ def printsolution(self, x):
...
ValueError: 7

>>> warnings.filters.pop(0)
('ignore', None, <class 'DeprecationWarning'>, None, 0)

# Re-enable DeprecationWarning: the (type, val, tb) exception representation is deprecated,
# and may be removed in a future version of Python.

Plain "raise" inside a generator should preserve the traceback (#13188).
The traceback should have 3 levels:
- g.throw()
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -2072,7 +2072,7 @@ def foo(): return gen
wrapper = foo()
wrapper.send(None)
with self.assertRaisesRegex(Exception, 'ham'):
wrapper.throw(Exception, Exception('ham'))
wrapper.throw(Exception('ham'))

# decorate foo second time
foo = types.coroutine(foo)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Emit a DeprecationWarning when :meth:`~generator.throw` or :meth:`~coroutine.throw` are called with more than one argument.
ofey404 marked this conversation as resolved.
Show resolved Hide resolved
17 changes: 15 additions & 2 deletions Objects/genobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) exception representation is deprecated, \n\
ofey404 marked this conversation as resolved.
Show resolved Hide resolved
and may be removed in a future version of Python.");
iritkatriel marked this conversation as resolved.
Show resolved Hide resolved

static PyObject *
_gen_throw(PyGenObject *gen, int close_on_genexit,
Expand Down Expand Up @@ -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, val, tb) exception representation is deprecated, "
"and may be removed in a future version of Python.",
iritkatriel marked this conversation as resolved.
Show resolved Hide resolved
ofey404 marked this conversation as resolved.
Show resolved Hide resolved
1) < 0) {
return NULL;
}
}
typ = args[0];
if (nargs == 3) {
val = args[1];
Expand Down Expand Up @@ -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) exception representation is deprecated, \n\
ofey404 marked this conversation as resolved.
Show resolved Hide resolved
and may be removed in a future version of Python.");


PyDoc_STRVAR(coro_close_doc,
"close() -> raise GeneratorExit inside coroutine.");
Expand Down