Update async features examples for Python 3.14 - #798
Open
lpozo wants to merge 2 commits into
Open
Conversation
Refresh the code for the "Getting Started With Async Features in Python" tutorial update. - Replace the `done`-flag loops with `while tasks:`, and iterate over a copy so removing an exhausted generator can't skip a task - Switch `asyncio.gather()` to `async with asyncio.TaskGroup()` in examples 4 and 6 (Python 3.11+) - Guard each HTTP request in example 6 with `asyncio.timeout(10)` - Rename the `queue` parameter to `work_queue` so it stops shadowing the `queue` module - Drop the stray `from builtins import range` in example 2 - Move the URL lists to https and replace the dead entries (twitter.com now redirects to x.com, yahoo.com returns 404) - Refresh requirements.txt to current releases and drop the transitive pins All six examples verified on Python 3.14.6. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Follow-up to the Python 3.14 refresh, applying review feedback on the sample code for "Getting Started With Async Features in Python". - Replace the `else` branch in example 1 with an early `return`, so the main loop body isn't indented behind a conditional - Name the loop variables in example 1's runner (`task_func`, `task_name`, `tasks_queue`) instead of `t`, `n`, `q` - Rename `t` to `current_task` in the generator-driving loops of examples 2, 3, and 5 - Use `_` for the unused counter variable in examples 1 and 2 - Extract the URL lists in examples 5 and 6 into a `urls` variable rather than inlining them in the `for` statement header - Drop the boilerplate docstrings and step comments, which restated what the code already says All six examples verified on Python 3.14.6 against the tutorial output. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Refreshes the sample code for understanding-asynchronous-programming, which backs Getting Started With Async Features in Python. Paired with the light update on that tutorial (CMS clone: post 2283).
The repo copy had drifted further than the article itself — it still pinned
aiohttp==3.5.4andrequests==2.21.0from 2019.Correctness and modernization
while tasks:instead of thedoneflag (examples 2, 3, 5). This came from a reader suggestion, and it also fixes a latent bug: the old loop removed items fromtaskswhile iterating over it, which can skip a task. The loop now iterates overtasks.copy().asyncio.gather()→async with asyncio.TaskGroup()(examples 4 and 6). Task groups are the recommended default since Python 3.11 and cancel remaining tasks when one fails.asyncio.timeout(10)around the HTTP request in example 6, so an unresponsive server can't stall a task indefinitely.queueparameter towork_queuein examples 2 and 3, where it was shadowing thequeuemodule.from builtins import rangein example 2 (an IDE artifact — it's a no-op on Python 3).https://, with the dead entries replaced.twitter.comnow redirects tox.com, andyahoo.comreturns 404 over https, so it was dropped.requirements.txtrefreshed to current releases, keeping only the three direct dependencies rather than the full frozen transitive set.Readability
A second pass after review of the article's code blocks:
returninstead of anelsebranch in example 1, so the main loop body isn't indented behind a conditional.task_func,task_name,tasks_queuerather thant,n,q.t→current_taskin the generator-driving loops of examples 2, 3, and 5._for the unused counter in examples 1 and 2.urlsvariable in examples 5 and 6, instead of being inlined in theforstatement header.Example 1 keeps its list of
(function, name, queue)tuples on purpose. Deferring the call is exactly the thing example 2 changes whentask()becomes a generator, so the two files stay minimally different.Verification
All six examples run on Python 3.14.6 with the pinned requirements:
example_1.pyexample_2.pyexample_3.pyexample_4.pyexample_5.pyexample_6.pyExamples 5 and 6 hit the live network, so their timings vary between runs. The async version stays roughly twice as fast as the sync one, which is the point the tutorial makes.
black -l 79andflake8 --max-line-length 79are both clean.The code here is semantically identical to the code blocks in the updated article, verified line by line. This repo's PEP 8 blank-line formatting is preserved, including the blank line between the standard-library and third-party import groups — the article renders the same code with single blank lines, so the tutorial's
python -m asyncio pstreeoutput cites the line numbers from these files (example_4.py:12and:22) and says so in a note.🤖 Generated with Claude Code