You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
aiter() and anext() call __aiter__ and __anext__ unbound #161394
Since aiter() and anext() were reimplemented in Python (gh-157361), they call __aiter__ and __anext__ unbound with the iterator as an argument, instead of binding them to the iterator as async for does. Anything that is not a plain function breaks, including unittest.mock:
fromunittestimportmockaiter(mock.MagicMock())
TypeError: _get_async_iter.<locals>.__aiter__() takes 0 positional arguments but 1 was given
AssertionError: expected await not found.
Expected: __anext__()
Actual: __anext__(<MagicMock id='138916121566848'>)
A staticmethod or another descriptor used as __aiter__ or __anext__ raises TypeError the same way, while async for over the same object works. An __anext__ defined only on the metaclass is now accepted as well. Both snippets pass on 3.14.
Expected: aiter() and anext() call these methods the same way async for does.
Have you tried this with anything other than a mock? Or is the mock the only thing that fails? Because the general rule for calling dunder methods is that, indeed, we look up the unbound dunder on the class (which searches for it through the MRO) and call it with the instance as first argument -- this is done because we don't want to incur the additional lookup overhead on the instance.
Activity
deadlovelll commentedon Nov 5, 2026
hi @fedonman! If you don't mind i can look at this and solve it =)
picnixz commentedon Nov 5, 2026
cc @kumaraditya303
gvanrossum commentedon Nov 5, 2026
Have you tried this with anything other than a mock? Or is the mock the only thing that fails? Because the general rule for calling dunder methods is that, indeed, we look up the unbound dunder on the class (which searches for it through the MRO) and call it with the instance as first argument -- this is done because we don't want to incur the additional lookup overhead on the instance.