Skip to content

Commit a2ab572

Browse files
committed
Use weakref for bound stream _response.
This avoids creating reference cycles that can result in significant extra memory usage. The cyclic GC should clean up the cycles but avoiding them is better.
1 parent ae1b9f6 commit a2ab572

1 file changed

Lines changed: 10 additions & 4 deletions

File tree

httpx/_client.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import time
77
import typing
88
import warnings
9+
import weakref
910
from contextlib import asynccontextmanager, contextmanager
1011
from types import TracebackType
1112

@@ -146,7 +147,7 @@ def __init__(
146147
self, stream: SyncByteStream, response: Response, start: float
147148
) -> None:
148149
self._stream = stream
149-
self._response = response
150+
self._response = weakref.ref(response)
150151
self._start = start
151152

152153
def __iter__(self) -> typing.Iterator[bytes]:
@@ -155,7 +156,9 @@ def __iter__(self) -> typing.Iterator[bytes]:
155156

156157
def close(self) -> None:
157158
elapsed = time.perf_counter() - self._start
158-
self._response.elapsed = datetime.timedelta(seconds=elapsed)
159+
response = self._response()
160+
if response is not None:
161+
response.elapsed = datetime.timedelta(seconds=elapsed)
159162
self._stream.close()
160163

161164

@@ -169,7 +172,7 @@ def __init__(
169172
self, stream: AsyncByteStream, response: Response, start: float
170173
) -> None:
171174
self._stream = stream
172-
self._response = response
175+
self._response = weakref.ref(response)
173176
self._start = start
174177

175178
async def __aiter__(self) -> typing.AsyncIterator[bytes]:
@@ -178,7 +181,10 @@ async def __aiter__(self) -> typing.AsyncIterator[bytes]:
178181

179182
async def aclose(self) -> None:
180183
elapsed = time.perf_counter() - self._start
181-
self._response.elapsed = datetime.timedelta(seconds=elapsed)
184+
response = self._response()
185+
if response is not None:
186+
assert 0
187+
response.elapsed = datetime.timedelta(seconds=elapsed)
182188
await self._stream.aclose()
183189

184190

0 commit comments

Comments
 (0)