From 6e623f4b5753e83f1687fbb9ef8200c8644a63a5 Mon Sep 17 00:00:00 2001 From: Fidget-Spinner <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 19 Jan 2021 23:26:44 +0800 Subject: [PATCH 01/10] Add to whatsnew in python 3.10 --- Doc/whatsnew/3.10.rst | 46 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 7edc552d824abb..e9ec7848b1a576 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -558,6 +558,12 @@ Removed the :mod:`collections` module. (Contributed by Victor Stinner in :issue:`37324`.) +* Removed the ``loop`` parameter of nearly all :mod:`asyncio` functions and + classes. This parameter was marked for deprecation in Python 3.8. See + `Changes in the Python API`_ for examples of how to replace existing code. + (Contributed by Yurii Karabas, Andrew Svetlov, Yury Selivanov and Kyle Stanley + in :issue:`42392`.) + Porting to Python 3.10 ====================== @@ -596,6 +602,46 @@ Changes in the Python API a 16-bit unsigned integer. (Contributed by Erlend E. Aasland in :issue:`42393`.) +* The ``loop`` parameter to nearly all :mod:`asyncio` functions has been + removed following deprecation in Python 3.8. Users should instead get the + current event loop inside of coroutines preferrably via + :func:`asyncio.get_running_loop` or :func:`asyncio.get_event_loop`. For + example, a coroutine that currently look like this:: + + async def foo(loop): + ... + + Can be replaced with this:: + + import asyncio + + async def foo(): + # Note that this asserts the loop is already running. + loop = asyncio.get_running_loop() + ... + + A minimal thread-safe version:: + + import asyncio + import threading + + lock = threading.Lock() + + def get_loop(): + global lock + with lock: + # Note that this asserts the loop is already running. + return asyncio.get_running_loop() + + async def foo(): + loop = get_loop() + ... + Users can also store the result of :func:`asyncio.get_event_loop` should + they wish to avoid the slight performance overhead of always calling the + function. Note that this requires additional thread safety and loop checks. + + (Contributed by Yurii Karabas, Andrew Svetlov, Yury Selivanov and Kyle Stanley + in :issue:`42392`.) CPython bytecode changes ======================== From 37ba9f0f652bc20b976265cc151ad557ce4764c9 Mon Sep 17 00:00:00 2001 From: Fidget-Spinner <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 19 Jan 2021 23:51:16 +0800 Subject: [PATCH 02/10] Add note about 3.6 --- Doc/whatsnew/3.10.rst | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index e9ec7848b1a576..bffcdfbadb7fd9 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -605,8 +605,9 @@ Changes in the Python API * The ``loop`` parameter to nearly all :mod:`asyncio` functions has been removed following deprecation in Python 3.8. Users should instead get the current event loop inside of coroutines preferrably via - :func:`asyncio.get_running_loop` or :func:`asyncio.get_event_loop`. For - example, a coroutine that currently look like this:: + :func:`asyncio.get_running_loop` (Python 3.7 and above) or + :func:`asyncio.get_event_loop`. For example, a coroutine that currently look + like this:: async def foo(loop): ... @@ -640,6 +641,12 @@ Changes in the Python API they wish to avoid the slight performance overhead of always calling the function. Note that this requires additional thread safety and loop checks. + Maintaining backwards compatibility with 3.6 code is slightly trickier. + Previous code using :mod:`asyncio` functions and classes, passing the loop + explicitly and relying on special behavior will error on 3.10. A possible + option is to guard the old call with a check for Python versions before 3.6 + and use the new call signature for newer versions. + (Contributed by Yurii Karabas, Andrew Svetlov, Yury Selivanov and Kyle Stanley in :issue:`42392`.) From b303cc5eebe976376e9d57ff17f05eea09957c35 Mon Sep 17 00:00:00 2001 From: Fidget-Spinner <28750310+Fidget-Spinner@users.noreply.github.com> Date: Tue, 19 Jan 2021 23:55:42 +0800 Subject: [PATCH 03/10] 3.6 -> 3.7 --- Doc/whatsnew/3.10.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index bffcdfbadb7fd9..508240a6987990 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -644,7 +644,7 @@ Changes in the Python API Maintaining backwards compatibility with 3.6 code is slightly trickier. Previous code using :mod:`asyncio` functions and classes, passing the loop explicitly and relying on special behavior will error on 3.10. A possible - option is to guard the old call with a check for Python versions before 3.6 + option is to guard the old call with a check for Python versions before 3.7 and use the new call signature for newer versions. (Contributed by Yurii Karabas, Andrew Svetlov, Yury Selivanov and Kyle Stanley From a9140da16e1c0f6aeb58add92ca920965df2ce93 Mon Sep 17 00:00:00 2001 From: Fidget-Spinner <28750310+Fidget-Spinner@users.noreply.github.com> Date: Wed, 20 Jan 2021 00:10:43 +0800 Subject: [PATCH 04/10] fix build errors --- Doc/whatsnew/3.10.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 508240a6987990..5a741324ba5f7c 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -637,6 +637,7 @@ Changes in the Python API async def foo(): loop = get_loop() ... + Users can also store the result of :func:`asyncio.get_event_loop` should they wish to avoid the slight performance overhead of always calling the function. Note that this requires additional thread safety and loop checks. From 102b58ba3ce5da3fc863347770a0dc2ddb9b2dd4 Mon Sep 17 00:00:00 2001 From: Fidget-Spinner <28750310+Fidget-Spinner@users.noreply.github.com> Date: Wed, 20 Jan 2021 01:18:10 +0800 Subject: [PATCH 05/10] use more relevant examples --- Doc/whatsnew/3.10.rst | 40 ++++++++-------------------------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 5a741324ba5f7c..e71a42b26c5374 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -602,45 +602,21 @@ Changes in the Python API a 16-bit unsigned integer. (Contributed by Erlend E. Aasland in :issue:`42393`.) -* The ``loop`` parameter to nearly all :mod:`asyncio` functions has been - removed following deprecation in Python 3.8. Users should instead get the - current event loop inside of coroutines preferrably via - :func:`asyncio.get_running_loop` (Python 3.7 and above) or - :func:`asyncio.get_event_loop`. For example, a coroutine that currently look - like this:: - - async def foo(loop): - ... - - Can be replaced with this:: +* The ``loop`` parameter to nearly all :mod:`asyncio` functions has been removed + following deprecation in Python 3.8. For example, a coroutine that currently + look like this:: import asyncio - async def foo(): - # Note that this asserts the loop is already running. - loop = asyncio.get_running_loop() - ... + async def foo(loop): + await asyncio.sleep(loop=loop) - A minimal thread-safe version:: + Can *usually* be replaced with this:: import asyncio - import threading - lock = threading.Lock() - - def get_loop(): - global lock - with lock: - # Note that this asserts the loop is already running. - return asyncio.get_running_loop() - - async def foo(): - loop = get_loop() - ... - - Users can also store the result of :func:`asyncio.get_event_loop` should - they wish to avoid the slight performance overhead of always calling the - function. Note that this requires additional thread safety and loop checks. + async def foo(loop): + await asyncio.sleep() Maintaining backwards compatibility with 3.6 code is slightly trickier. Previous code using :mod:`asyncio` functions and classes, passing the loop From 532f484143be443aa0416a1f53bbeab7f0443e10 Mon Sep 17 00:00:00 2001 From: Fidget-Spinner <28750310+Fidget-Spinner@users.noreply.github.com> Date: Wed, 20 Jan 2021 01:30:43 +0800 Subject: [PATCH 06/10] remove confusing paragraph --- Doc/whatsnew/3.10.rst | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index e71a42b26c5374..57f0fdc6084088 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -618,12 +618,6 @@ Changes in the Python API async def foo(loop): await asyncio.sleep() - Maintaining backwards compatibility with 3.6 code is slightly trickier. - Previous code using :mod:`asyncio` functions and classes, passing the loop - explicitly and relying on special behavior will error on 3.10. A possible - option is to guard the old call with a check for Python versions before 3.7 - and use the new call signature for newer versions. - (Contributed by Yurii Karabas, Andrew Svetlov, Yury Selivanov and Kyle Stanley in :issue:`42392`.) From 474014a4eff626713fa4c57de7c749095998801f Mon Sep 17 00:00:00 2001 From: Fidget-Spinner <28750310+Fidget-Spinner@users.noreply.github.com> Date: Wed, 20 Jan 2021 17:03:35 +0800 Subject: [PATCH 07/10] apply suggestions by everyone Co-Authored-By: Kyle Stanley --- Doc/whatsnew/3.10.rst | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 57f0fdc6084088..61050190a4be44 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -558,9 +558,10 @@ Removed the :mod:`collections` module. (Contributed by Victor Stinner in :issue:`37324`.) -* Removed the ``loop`` parameter of nearly all :mod:`asyncio` functions and - classes. This parameter was marked for deprecation in Python 3.8. See - `Changes in the Python API`_ for examples of how to replace existing code. +* The ``loop`` parameter has been removed from most of :mod:`asyncio` + :doc:`high-level API <../library/asyncio-api-index>` following deprecation + in Python 3.8. See `Changes in the Python API`_ for the reasoning behind the + change, and examples of how to replace existing code. (Contributed by Yurii Karabas, Andrew Svetlov, Yury Selivanov and Kyle Stanley in :issue:`42392`.) @@ -602,21 +603,32 @@ Changes in the Python API a 16-bit unsigned integer. (Contributed by Erlend E. Aasland in :issue:`42393`.) -* The ``loop`` parameter to nearly all :mod:`asyncio` functions has been removed - following deprecation in Python 3.8. For example, a coroutine that currently - look like this:: +* The ``loop`` parameter has been removed from most of :mod:`asyncio` + :doc:`high-level API <../library/asyncio-api-index>` following deprecation + in Python 3.8. The motivation behind this change is multifold: - import asyncio + 1. This simplifies the high-level API. + 2. The functions in the high-level API have been implicitly getting the + current thread's running event loop since Python 3.6. There isn't a need to + pass the event loop to the API in most normal use cases. + 3. Event loop passing is error-prone especially when dealing with loops + running in different threads. + + Note that the low-level API has **not** been affected. + + A coroutine that currently look like this:: async def foo(loop): - await asyncio.sleep(loop=loop) + await asyncio.sleep(1, loop=loop) - Can *usually* be replaced with this:: + Should be replaced with this:: - import asyncio + async def foo(): + await asyncio.sleep(1) - async def foo(loop): - await asyncio.sleep() + If ``foo()`` was specifically designed *not* to run in the current thread's + running event loop (eg. running in another thread's event loop), consider + using :func:`asyncio.run_coroutine_threadsafe` instead. (Contributed by Yurii Karabas, Andrew Svetlov, Yury Selivanov and Kyle Stanley in :issue:`42392`.) From 452a596b312cb921c7cddb42c122513c40abb2fa Mon Sep 17 00:00:00 2001 From: Fidget-Spinner <28750310+Fidget-Spinner@users.noreply.github.com> Date: Wed, 20 Jan 2021 17:10:38 +0800 Subject: [PATCH 08/10] add an apostrophe --- Doc/whatsnew/3.10.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 61050190a4be44..308c055b67d8d9 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -558,7 +558,7 @@ Removed the :mod:`collections` module. (Contributed by Victor Stinner in :issue:`37324`.) -* The ``loop`` parameter has been removed from most of :mod:`asyncio` +* The ``loop`` parameter has been removed from most of :mod:`asyncio`\ 's :doc:`high-level API <../library/asyncio-api-index>` following deprecation in Python 3.8. See `Changes in the Python API`_ for the reasoning behind the change, and examples of how to replace existing code. @@ -603,7 +603,7 @@ Changes in the Python API a 16-bit unsigned integer. (Contributed by Erlend E. Aasland in :issue:`42393`.) -* The ``loop`` parameter has been removed from most of :mod:`asyncio` +* The ``loop`` parameter has been removed from most of :mod:`asyncio`\ 's :doc:`high-level API <../library/asyncio-api-index>` following deprecation in Python 3.8. The motivation behind this change is multifold: From 5ce1b6ad80cbf8e9b1f32e3c664e304dc1057dba Mon Sep 17 00:00:00 2001 From: Fidget-Spinner <28750310+Fidget-Spinner@users.noreply.github.com> Date: Wed, 20 Jan 2021 18:56:10 +0800 Subject: [PATCH 09/10] apply victor's suggestions --- Doc/whatsnew/3.10.rst | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 308c055b67d8d9..cd4c6660e5803f 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -560,8 +560,18 @@ Removed * The ``loop`` parameter has been removed from most of :mod:`asyncio`\ 's :doc:`high-level API <../library/asyncio-api-index>` following deprecation - in Python 3.8. See `Changes in the Python API`_ for the reasoning behind the - change, and examples of how to replace existing code. + in Python 3.8. The motivation behind this change is multifold: + + 1. This simplifies the high-level API. + 2. The functions in the high-level API have been implicitly getting the + current thread's running event loop since Python 3.6. There isn't a need to + pass the event loop to the API in most normal use cases. + 3. Event loop passing is error-prone especially when dealing with loops + running in different threads. + + Note that the low-level API will still accept ``loop``. + See `Changes in the Python API`_ for examples of how to replace existing code. + (Contributed by Yurii Karabas, Andrew Svetlov, Yury Selivanov and Kyle Stanley in :issue:`42392`.) @@ -605,16 +615,7 @@ Changes in the Python API * The ``loop`` parameter has been removed from most of :mod:`asyncio`\ 's :doc:`high-level API <../library/asyncio-api-index>` following deprecation - in Python 3.8. The motivation behind this change is multifold: - - 1. This simplifies the high-level API. - 2. The functions in the high-level API have been implicitly getting the - current thread's running event loop since Python 3.6. There isn't a need to - pass the event loop to the API in most normal use cases. - 3. Event loop passing is error-prone especially when dealing with loops - running in different threads. - - Note that the low-level API has **not** been affected. + in Python 3.8. A coroutine that currently look like this:: From 45ae76f457772c97ba94cdda9be8096f0227661d Mon Sep 17 00:00:00 2001 From: Fidget-Spinner <28750310+Fidget-Spinner@users.noreply.github.com> Date: Thu, 21 Jan 2021 07:22:20 +0800 Subject: [PATCH 10/10] apply suggestions by kyle Co-Authored-By: Kyle Stanley --- Doc/whatsnew/3.10.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index cd4c6660e5803f..423d3cee7b3637 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -564,7 +564,7 @@ Removed 1. This simplifies the high-level API. 2. The functions in the high-level API have been implicitly getting the - current thread's running event loop since Python 3.6. There isn't a need to + current thread's running event loop since Python 3.7. There isn't a need to pass the event loop to the API in most normal use cases. 3. Event loop passing is error-prone especially when dealing with loops running in different threads. @@ -628,7 +628,7 @@ Changes in the Python API await asyncio.sleep(1) If ``foo()`` was specifically designed *not* to run in the current thread's - running event loop (eg. running in another thread's event loop), consider + running event loop (e.g. running in another thread's event loop), consider using :func:`asyncio.run_coroutine_threadsafe` instead. (Contributed by Yurii Karabas, Andrew Svetlov, Yury Selivanov and Kyle Stanley