Skip to content

gh-157361: Implement anext() in Python instead of C - #157362

Open
kumaraditya303 wants to merge 5 commits into
python:mainfrom
kumaraditya303:anext-in-python
Open

gh-157361: Implement anext() in Python instead of C#157362
kumaraditya303 wants to merge 5 commits into
python:mainfrom
kumaraditya303:anext-in-python

Conversation

@kumaraditya303

@kumaraditya303 kumaraditya303 commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Remove the C implementation of the anext() builtin and the anext_awaitable helper type. A _pybuiltins module is created with the implementation and that is frozen into the interpreter using the existing freeze infrastructure.

The Python version keeps the C semantics: __anext__ is looked up on the type and called eagerly, the one-argument form returns the awaitable unchanged, and the two-argument form wraps it in a coroutine that returns the default on StopAsyncIteration.

I'll implement aiter similarly in a followup.

Remove the C implementation of the anext() builtin and the
anext_awaitable helper type. Instead, compile a small Python source at
interpreter startup and copy the resulting anext() function into the
builtins dict.

The Python version keeps the C semantics: __anext__ is looked up on the
type and called eagerly, the one-argument form returns the awaitable
unchanged, and the two-argument form wraps it in a coroutine that
returns the default on StopAsyncIteration.

The source is executed from pycore_init_builtins() rather than
_PyBuiltin_Init(), since running bytecode requires the interpreter's
common constants, which are only set up after the builtins module is
created.
Comment thread Lib/_builtins.py Outdated
Comment thread Lib/_pybuiltins.py
Comment thread Lib/_builtins.py
@kumaraditya303 kumaraditya303 added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Sep 13, 2026
@bedevere-bot

Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @kumaraditya303 for commit 9db7837 🤖

Results will be shown at:

https://buildbot.python.org/all/#/grid?branch=refs%2Fpull%2F157362%2Fmerge

If you want to schedule another build, you need to add the 🔨 test-with-buildbots label again.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Sep 13, 2026
Comment thread Lib/_pybuiltins.py
try:
# Looked up on the type, like the C slot am_anext.
anext_method = cls.__anext__
except AttributeError:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strictly speaking, there is now a slight divergence where accessing __anext__ could raise something other than an AttributeError and this would leak. Should we worry about those cases? (previoulsy we directly accessed the structs, so we were bypassing getattr).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

am_next is the underlying slot for __anext__ and the method is being looked up on the type so there isn't much divergence (the instance getattr cannot be triggered) so apart from contrived hand-crafted cases this is safe.

Comment thread Lib/_pybuiltins.py
anext_method = cls.__anext__
except AttributeError:
raise TypeError(
f"'{cls.__name__}' object is not an async iterator"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
f"'{cls.__name__}' object is not an async iterator"
f"{cls.__name__!r} object is not an async iterator"

@@ -0,0 +1,4 @@
Implement :func:`anext` in Python instead of C, in a frozen ``_pybuiltins``

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since it's a built-in change I think you should also mention it in What's New 3.16 because it's kind of a breaking change for anyone having a _pybuiltins momdule in their project.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll do that after I do the other ones as well like aiter.

Comment thread Lib/test/test_asyncgen.py
p = ait_class()
obj = anext(p, "completed")
self.assertRaises(SyntaxError, obj.throw, SyntaxError)
with warnings.catch_warnings():

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this a change of behavior then? maybe document it as well?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is but not important, throwing or sending something to just created generator always errors so in practice no one does it. The important part is that it raises exception for that and it does.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants