From d411bc511d4348e543a5690786c7100dc47d8eb9 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Mon, 25 Nov 2024 14:29:45 -0800 Subject: [PATCH] [PR #10043/5255cec backport][3.11] Avoid constructing headers mulitidict twice for ``web.Response`` (#10045) --- CHANGES/10043.misc.rst | 1 + aiohttp/web_response.py | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 CHANGES/10043.misc.rst diff --git a/CHANGES/10043.misc.rst b/CHANGES/10043.misc.rst new file mode 100644 index 00000000000..cfd4e88ee24 --- /dev/null +++ b/CHANGES/10043.misc.rst @@ -0,0 +1 @@ +Improved performance of constructing :class:`aiohttp.web.Response` with headers -- by :user:`bdraco`. diff --git a/aiohttp/web_response.py b/aiohttp/web_response.py index 59c9b54784a..d3d8afe5433 100644 --- a/aiohttp/web_response.py +++ b/aiohttp/web_response.py @@ -86,7 +86,15 @@ def __init__( status: int = 200, reason: Optional[str] = None, headers: Optional[LooseHeaders] = None, + _real_headers: Optional[CIMultiDict[str]] = None, ) -> None: + """Initialize a new stream response object. + + _real_headers is an internal parameter used to pass a pre-populated + headers object. It is used by the `Response` class to avoid copying + the headers when creating a new response object. It is not intended + to be used by external code. + """ self._body = None self._keep_alive: Optional[bool] = None self._chunked = False @@ -102,7 +110,9 @@ def __init__( self._body_length = 0 self._state: Dict[str, Any] = {} - if headers is not None: + if _real_headers is not None: + self._headers = _real_headers + elif headers is not None: self._headers: CIMultiDict[str] = CIMultiDict(headers) else: self._headers = CIMultiDict() @@ -660,7 +670,7 @@ def __init__( content_type += "; charset=" + charset real_headers[hdrs.CONTENT_TYPE] = content_type - super().__init__(status=status, reason=reason, headers=real_headers) + super().__init__(status=status, reason=reason, _real_headers=real_headers) if text is not None: self.text = text