From 65f1b79ce8613e576bc89cb5c4b73208589b1d78 Mon Sep 17 00:00:00 2001 From: Walter Oggioni Date: Sat, 18 Jul 2026 16:53:05 +0000 Subject: [PATCH] Fix SessionHttpContext to delegate attributes via __getattr__ The previous implementation eagerly copied ASGI-specific attributes (pathsend, receive, send) from the wrapped context, which crashed under RSGI because RsgiContext does not have those attributes. Now SessionHttpContext delegates all non-overridden attributes to the wrapped context via __getattr__, making it protocol-agnostic. --- .../kaya-session/src/kaya/session/_mixin.py | 26 +++++++++---------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/packages/kaya-session/src/kaya/session/_mixin.py b/packages/kaya-session/src/kaya/session/_mixin.py index 1b6d818..87f04e9 100644 --- a/packages/kaya-session/src/kaya/session/_mixin.py +++ b/packages/kaya-session/src/kaya/session/_mixin.py @@ -15,6 +15,10 @@ class SessionHttpContext(HttpContext): Works with any concrete ``HttpContext`` (ASGI or RSGI) because it only relies on the abstract send methods, which all implementations share. + Attributes not explicitly overridden are delegated to the wrapped context + via ``__getattr__``, so protocol-specific fields (``pathsend``, + ``receive``/``send`` for ASGI, ``protocol`` for RSGI, etc.) are passed + through transparently. """ def __init__( @@ -23,20 +27,14 @@ class SessionHttpContext(HttpContext): session: Session, cookie_injector: Callable[[], Optional[str]], ) -> None: - self._ctx = ctx - self.session = session - self._cookie_injector = cookie_injector - self.pathsend = ctx.pathsend - self.receive = ctx.receive - self.send = ctx.send - self.scheme = ctx.scheme - self.method = ctx.method - self.path = ctx.path - self.query_string = ctx.query_string - self.headers = ctx.headers - self.client = ctx.client - self.server = ctx.server - self.request_body = ctx.request_body + object.__setattr__(self, '_ctx', ctx) + object.__setattr__(self, 'session', session) + object.__setattr__(self, '_cookie_injector', cookie_injector) + + def __getattr__(self, name: str) -> Any: + if name == '_ctx': + raise AttributeError(name) + return getattr(self._ctx, name) def _inject_cookie(self, headers: Optional[Mapping[str, StrOrStrings]]) -> Optional[Mapping[str, StrOrStrings]]: cookie_value = self._cookie_injector()