Skip to content

feat(client): implement context manager protocol#533

Merged
0x676e67 merged 1 commit intomainfrom
feat
Mar 5, 2026
Merged

feat(client): implement context manager protocol#533
0x676e67 merged 1 commit intomainfrom
feat

Conversation

@0x676e67
Copy link
Copy Markdown
Owner

@0x676e67 0x676e67 commented Mar 5, 2026

No description provided.

@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces support for Python's context manager protocol to both the asynchronous Client and synchronous BlockingClient classes. This enhancement allows users to manage client lifecycles more cleanly and safely using with and async with statements, ensuring resources are properly acquired and released, even in the presence of exceptions. The change improves the API's ergonomics and robustness by aligning it with common Pythonic patterns for resource handling.

Highlights

  • Asynchronous Context Manager: Implemented the __aenter__ and __aexit__ methods for the Client class, allowing it to be used with async with statements for proper asynchronous resource management.
  • Synchronous Context Manager: Implemented the __enter__ and __exit__ methods for the BlockingClient class, enabling its use with standard with statements for synchronous resource management.
  • Type Hinting Updates: Updated type hints in python/rnet/__init__.pyi and python/rnet/blocking.py to reflect the new context manager protocols and to generalize __enter__ return types to Any where appropriate.
Changelog
  • python/rnet/init.pyi
    • Added __aenter__ and __aexit__ method signatures to the Client class for async context manager support.
  • python/rnet/blocking.py
    • Updated the return type hint of __enter__ from specific class names to Any for Response and WebSocket classes.
    • Added __enter__ and __exit__ method signatures to the Client class for synchronous context manager support.
  • src/client.rs
    • Implemented the __aenter__ and __aexit__ methods for the Client struct, exposing async context manager functionality to Python.
    • Implemented the __enter__ and __exit__ methods for the BlockingClient struct, exposing synchronous context manager functionality to Python.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request implements the context manager protocol for Client and BlockingClient. My review focuses on improving the Python type hints for correctness and consistency, and on the Rust implementation details. I've identified several areas where type hints can be more specific, which improves code clarity and helps static analysis tools. Additionally, the __exit__ methods are currently placeholders, which I've noted. I also suggest a minor code organization improvement in the Rust code.

Comment on lines +1358 to +1361
async def __aenter__(self) -> Any: ...
async def __aexit__(
self, _exc_type: Any, _exc_value: Any, _traceback: Any
) -> Any: ...
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The type hints for __aenter__ and __aexit__ can be more specific. __aenter__ should return an instance of the class, so its return type should be "Client". The __aexit__ method in the Rust implementation doesn't return a value, which corresponds to None in Python.

Suggested change
async def __aenter__(self) -> Any: ...
async def __aexit__(
self, _exc_type: Any, _exc_value: Any, _traceback: Any
) -> Any: ...
async def __aenter__(self) -> "Client": ...
async def __aexit__(
self, _exc_type: Any, _exc_value: Any, _traceback: Any
) -> None: ...

"""

def __enter__(self) -> "Response": ...
def __enter__(self) -> Any: ...
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The return type of __enter__ was changed from "Response" to Any. This is a regression in type hint specificity. The __enter__ method should return self, so the type hint should be "Response". Please revert this change.

Suggested change
def __enter__(self) -> Any: ...
def __enter__(self) -> "Response": ...

"""

def __enter__(self) -> "WebSocket": ...
def __enter__(self) -> Any: ...
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The return type of __enter__ was changed from "WebSocket" to Any. This is a regression in type hint specificity. The __enter__ method should return self, so the type hint should be "WebSocket". Please revert this change.

Suggested change
def __enter__(self) -> Any: ...
def __enter__(self) -> "WebSocket": ...

"""
...

def __enter__(self) -> Any: ...
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The __enter__ method should return an instance of the class itself. The type hint should be "Client" instead of Any for consistency with other context managers in the codebase.

Suggested change
def __enter__(self) -> Any: ...
def __enter__(self) -> "Client": ...

Comment on lines +596 to +598
async fn __aexit__(&self, _exc_type: Py<PyAny>, _exc_val: Py<PyAny>, _traceback: Py<PyAny>) {
// TODO: Implement connection closing logic if necessary.
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

The __aexit__ method is currently a placeholder. For a Client context manager to be useful, it should handle resource cleanup, such as closing connections. Please consider implementing the necessary cleanup logic here to fulfill the contract of a context manager.

Comment on lines +588 to +599
#[pymethods]
impl Client {
#[inline]
async fn __aenter__(slf: Py<Self>) -> PyResult<Py<Self>> {
Ok(slf)
}

#[inline]
async fn __aexit__(&self, _exc_type: Py<PyAny>, _exc_val: Py<PyAny>, _traceback: Py<PyAny>) {
// TODO: Implement connection closing logic if necessary.
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

For better code organization and readability, it's a good practice to consolidate all #[pymethods] for a single struct into one impl block. Consider merging this impl Client block with the one starting on line 250.

Comment on lines +756 to +764
fn __exit__<'py>(
&self,
_py: Python<'py>,
_exc_type: &Bound<'py, PyAny>,
_exc_value: &Bound<'py, PyAny>,
_traceback: &Bound<'py, PyAny>,
) {
// TODO: Implement connection closing logic if necessary.
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Similar to the Client, the __exit__ method for BlockingClient is a placeholder. To make the context manager useful, this method should implement resource cleanup logic, such as closing any open connections managed by the client.

Comment on lines +748 to +765
#[pymethods]
impl BlockingClient {
#[inline]
fn __enter__(slf: PyRef<Self>) -> PyRef<Self> {
slf
}

#[inline]
fn __exit__<'py>(
&self,
_py: Python<'py>,
_exc_type: &Bound<'py, PyAny>,
_exc_value: &Bound<'py, PyAny>,
_traceback: &Bound<'py, PyAny>,
) {
// TODO: Implement connection closing logic if necessary.
}
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

For better code organization and readability, it's a good practice to consolidate all #[pymethods] for a single struct into one impl block. Consider merging this impl BlockingClient block with the one starting on line 603.

@0x676e67 0x676e67 merged commit 3f76605 into main Mar 5, 2026
31 checks passed
@0x676e67 0x676e67 deleted the feat branch March 5, 2026 09:22
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