Skip to content

fix: add __aiter__ to AsyncCommandHandle for async iteration support#1192

Open
MaxwellCalkin wants to merge 1 commit intoe2b-dev:mainfrom
MaxwellCalkin:fix/async-command-handle-aiter
Open

fix: add __aiter__ to AsyncCommandHandle for async iteration support#1192
MaxwellCalkin wants to merge 1 commit intoe2b-dev:mainfrom
MaxwellCalkin:fix/async-command-handle-aiter

Conversation

@MaxwellCalkin
Copy link

Summary

Related to #1034

The sync CommandHandle supports iteration via __iter__:

handle = sandbox.commands.run("ls", background=True)
for stdout, stderr, pty in handle:
    print(stdout)

But AsyncCommandHandle lacks __aiter__, so the async equivalent fails:

handle = await sandbox.commands.run("ls", background=True)
async for stdout, stderr, pty in handle:  # TypeError: 'AsyncCommandHandle' object is not async iterable
    print(stdout)

This PR adds __aiter__ to AsyncCommandHandle, delegating to the existing _iterate_events() async generator — mirroring the sync __iter___handle_events() pattern.

Changes

  • packages/python-sdk/e2b/sandbox_async/commands/command_handle.py: Added __aiter__ method (8 lines)

AI Disclosure

This PR was authored by Claude Opus 4.6 (Anthropic), an AI agent operated by Maxwell Calkin (@MaxwellCalkin). See our portfolio for more about this project.

The sync CommandHandle supports `for stdout, stderr, pty in handle:`
via __iter__, but AsyncCommandHandle lacks __aiter__, preventing
`async for stdout, stderr, pty in handle:` usage.

This adds __aiter__ mirroring the sync __iter__ pattern, delegating
to the existing _iterate_events() async generator.

Related to e2b-dev#1034

AI Disclosure: This commit was authored by Claude Opus 4.6 (Anthropic),
operated by Maxwell Calkin (@MaxwellCalkin).
@changeset-bot
Copy link

changeset-bot bot commented Mar 9, 2026

⚠️ No Changeset found

Latest commit: ad4e2b6

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ad4e2b6c27

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


:return: Async generator of command outputs
"""
return self._iterate_events().__aiter__()

Choose a reason for hiding this comment

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

P1 Badge Avoid a second consumer in __aiter__

AsyncCommandHandle already starts self._wait = asyncio.create_task(self._handle_events()) in __init__, so the event stream is being consumed immediately in the background; returning a fresh self._iterate_events() iterator here introduces a second concurrent consumer of the same async generator. In the intended usage (async for ... in handle), this can raise RuntimeError: anext(): asynchronous generator is already running (or silently drain events in one consumer), so the new async-iteration API is not reliably usable.

Useful? React with 👍 / 👎.

@ValentaTomas ValentaTomas removed their request for review March 12, 2026 02:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant