AsyncOAuth2Client missing async context manager protocol (__aenter__, __aexit__)
- Vorherrschende Sprache
- Python
- Sterne
- 5.1k
- Forks
- 2.1k
- Ø Merge
- 1 T. 19 Std.
- Gemergte PRs (30 T.)
- 82
Beschreibung
Problem
The AsyncOAuth2Client class in stubs/Authlib/authlib/integrations/httpx_client/oauth2_client.pyi is missing type annotations for the async context manager protocol (__aenter__ and __aexit__), causing type checkers to incorrectly flag valid async with usage as errors.
Expected Behavior
AsyncOAuth2Client should be usable as an async context manager since it inherits from httpx.AsyncClient at runtime:
from authlib.integrations.httpx_client import AsyncOAuth2Client
async with AsyncOAuth2Client(client_id="...", client_secret="...") as client:
response = await client.get("https://api.example.com/data")
Actual Behavior
Pyright reports errors:
error: Object of type "AsyncOAuth2Client" cannot be used with "async with" because it does not correctly implement __aenter__
Attribute "__aenter__" is unknown (reportGeneralTypeIssues)
error: Object of type "AsyncOAuth2Client" cannot be used with "with" because it does not correctly implement __aexit__
Attribute "__aexit__" is unknown (reportGeneralTypeIssues)
Root Cause
The stub file at line 26-27 shows:
# Inherits from httpx.AsyncClient
class AsyncOAuth2Client(_OAuth2Client):
The comment is correct but the type stub is incomplete. The class should expose the async context manager protocol from httpx.AsyncClient, but it's not properly modeled in the stubs.
Runtime Verification
At runtime, AsyncOAuth2Client does have these methods:
from authlib.integrations.httpx_client import AsyncOAuth2Client
print(hasattr(AsyncOAuth2Client, '__aenter__')) # True
print(hasattr(AsyncOAuth2Client, '__aexit__')) # True
Proposed Fix
Update stubs/Authlib/authlib/integrations/httpx_client/oauth2_client.pyi to explicitly declare the async context manager protocol:
from typing_extensions import Self
class AsyncOAuth2Client(_OAuth2Client):
SESSION_REQUEST_PARAMS: list[str]
client_auth_class = OAuth2ClientAuth
token_auth_class = OAuth2Auth
oauth_error_class = OAuthError
def __init__(
self,
client_id=None,
client_secret=None,
token_endpoint_auth_method=None,
revocation_endpoint_auth_method=None,
scope=None,
redirect_uri=None,
token=None,
token_placement="header",
update_token=None,
leeway=60,
**kwargs,
) -> None: ...
async def __aenter__(self) -> Self: ...
async def __aexit__(self, exc_type, exc_val, exc_tb) -> None: ...
async def request(self, method, url, withhold_token: bool = False, auth=..., **kwargs): ...
async def stream(self, method, url, withhold_token: bool = False, auth=..., **kwargs) -> Generator[Incomplete]: ...
async def ensure_active_token(self, token): ...
Similarly, OAuth2Client (the sync version) may need __enter__ and __exit__ methods.
Affected Versions
types-Authlib>=1.4.0(when httpx_client stubs were added in PR #15147)- Works correctly in
types-Authlib==1.3.0.20241229(no httpx_client stubs existed)
Related Files
stubs/Authlib/authlib/integrations/httpx_client/oauth2_client.pyi(line 26-48)
Labels to add: stubs: incomplete
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Rechercherichtung
Beginne mit stubs/Authlib/authlib/integrations/httpx_client/oauth2_client.pyi, insbesondere mit der AsyncOAuth2Client-Deklaration um die Zeilen 26–48, und prüfe den verknüpften Pull Request #15190. Überprüfe das async with-Beispiel mit Pyright; als abgeschlossen gilt die Aufgabe, wenn der Stub das Laufzeitverhalten als Context Manager ohne diese Protokollfehler offenlegt und die mögliche sync OAuth2Client-Frage berücksichtigt ist, falls sie in scope ist.
Vom Indexierungsmodell aus dem Issue-Text verfasst.
Bewertung
- Tech-Stack
- python
- Bereich
- tooling
- Issue-Typ
- Bug
- Schwierigkeit
- 2/5
- Geschätzter Aufwand
- 1-3 Stunden
- Aktivitätsstatus
- Veraltet
- Klarheit
- Klar beschrieben
- Anfängerfreundlichkeit
- 25/100