Skip to content

fix(python): fix SimpleBox.shutdown() crash on missing method#246

Merged
DorianZheng merged 2 commits intomainfrom
fix/simplebox-shutdown
Feb 13, 2026
Merged

fix(python): fix SimpleBox.shutdown() crash on missing method#246
DorianZheng merged 2 commits intomainfrom
fix/simplebox-shutdown

Conversation

@yingjunwu
Copy link
Copy Markdown
Contributor

Summary

  • Fix SimpleBox.shutdown() calling self._box.shutdown() which doesn't exist on the Rust Box — only stop() is exposed
  • Add async stop() method that correctly calls self._box.stop()
  • Make shutdown() an async alias for stop()

Test plan

  • await box.shutdown() works without AttributeError
  • await box.stop() works as a direct alternative
  • Context manager cleanup still works

Closes #229

🤖 Generated with Claude Code

SimpleBox.shutdown() called self._box.shutdown(), but the underlying
Rust Box only exposes stop(), not shutdown(). This caused:
  AttributeError: 'builtins.Box' object has no attribute 'shutdown'

Fix:
- Add async stop() method that calls self._box.stop()
- Make shutdown() an async alias for stop()
- Both methods are now properly async (the old shutdown was sync)

Closes #229

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes a critical bug in SimpleBox.shutdown() where it was calling a non-existent shutdown() method on the underlying Rust Box object, causing an AttributeError. The fix correctly calls the existing stop() method and also makes both shutdown() and the new stop() methods async, which is required since the underlying Rust methods are async.

Changes:

  • Renamed the broken shutdown() method to stop() and made it properly async
  • Fixed the method call from self._box.shutdown() (doesn't exist) to await self._box.stop() (correct)
  • Added shutdown() as an async alias for stop() to maintain backward compatibility with code expecting a shutdown() method

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 282 to +301
@@ -290,7 +290,15 @@ def shutdown(self):
"Box not started. Use 'async with SimpleBox(...) as box:' "
"or call 'await box.start()' first."
)
self._box.shutdown()
await self._box.stop()

async def shutdown(self):
"""
Shutdown the box and release resources.

Alias for stop(). Usually not needed as context manager handles cleanup.
"""
await self.stop()
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

The synchronous wrapper SyncSimpleBox (in sdks/python/boxlite/sync_api/_simplebox.py) has a stop() method but no shutdown() method. For API consistency, consider adding a shutdown() alias in SyncSimpleBox as well, similar to what's being done here for the async SimpleBox.

Copilot uses AI. Check for mistakes.
Comment on lines 282 to +301
@@ -290,7 +290,15 @@ def shutdown(self):
"Box not started. Use 'async with SimpleBox(...) as box:' "
"or call 'await box.start()' first."
)
self._box.shutdown()
await self._box.stop()

async def shutdown(self):
"""
Shutdown the box and release resources.

Alias for stop(). Usually not needed as context manager handles cleanup.
"""
await self.stop()
Copy link

Copilot AI Feb 12, 2026

Choose a reason for hiding this comment

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

Consider adding test coverage for the new stop() and shutdown() methods. While test_simplebox.py has comprehensive tests for other SimpleBox methods like exec(), info(), and the context manager, there are no tests for explicit shutdown/stop calls. Tests should verify:

  1. await box.stop() works without errors after starting the box
  2. await box.shutdown() works as an alias for stop()
  3. Both methods raise RuntimeError when called before starting the box
  4. Multiple calls to stop()/shutdown() are handled gracefully

Copilot uses AI. Check for mistakes.
@yingjunwu
Copy link
Copy Markdown
Contributor Author

Self-review: This PR looks correct.

The bug: SimpleBox.shutdown() was sync and called self._box.shutdown() which doesn't exist on the Rust Box handle (only stop() exists).

The fix:

  • Adds async def stop() that calls await self._box.stop() (confirmed async in box_handle.rs:82)
  • Keeps shutdown() as an async alias for backwards compatibility

No impact on SyncSimpleBox — it already has its own stop() method and never had shutdown().

Copilot AI review requested due to automatic review settings February 13, 2026 01:46
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@DorianZheng DorianZheng merged commit 537a5f8 into main Feb 13, 2026
19 checks passed
@DorianZheng DorianZheng deleted the fix/simplebox-shutdown branch February 13, 2026 01:48
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.

SimpleBox.shutdown() crashes: underlying Box has no 'shutdown' attribute

3 participants