MCPcopy Create free account
hub / github.com/anthropics/anthropic-sdk-python / test_copy_build_request

Method test_copy_build_request

tests/test_client.py:266–326  ·  view source on GitHub ↗
(self, client: Anthropic)

Source from the content-addressed store, hash-verified

264
265 @pytest.mark.skipif(sys.version_info >= (3, 10), reason="fails because of a memory leak that started from 3.12")
266 def test_copy_build_request(self, client: Anthropic) -> None:
267 options = FinalRequestOptions(method="get", url="/foo")
268
269 def build_request(options: FinalRequestOptions) -> None:
270 client_copy = client.copy()
271 client_copy._build_request(options)
272
273 # ensure that the machinery is warmed up before tracing starts.
274 build_request(options)
275 gc.collect()
276
277 tracemalloc.start(1000)
278
279 snapshot_before = tracemalloc.take_snapshot()
280
281 ITERATIONS = 10
282 for _ in range(ITERATIONS):
283 build_request(options)
284
285 gc.collect()
286 snapshot_after = tracemalloc.take_snapshot()
287
288 tracemalloc.stop()
289
290 def add_leak(leaks: list[tracemalloc.StatisticDiff], diff: tracemalloc.StatisticDiff) -> None:
291 if diff.count == 0:
292 # Avoid false positives by considering only leaks (i.e. allocations that persist).
293 return
294
295 if diff.count % ITERATIONS != 0:
296 # Avoid false positives by considering only leaks that appear per iteration.
297 return
298
299 for frame in diff.traceback:
300 if any(
301 frame.filename.endswith(fragment)
302 for fragment in [
303 # to_raw_response_wrapper leaks through the @functools.wraps() decorator.
304 #
305 # removing the decorator fixes the leak for reasons we don't understand.
306 "anthropic/_legacy_response.py",
307 "anthropic/_response.py",
308 # pydantic.BaseModel.model_dump || pydantic.BaseModel.dict leak memory for some reason.
309 "anthropic/_compat.py",
310 # Standard library leaks we don't care about.
311 "/logging/__init__.py",
312 ]
313 ):
314 return
315
316 leaks.append(diff)
317
318 leaks: list[tracemalloc.StatisticDiff] = []
319 for diff in snapshot_after.compare_to(snapshot_before, "traceback"):
320 add_leak(leaks, diff)
321 if leaks:
322 for leak in leaks:
323 print("MEMORY LEAK:", leak)

Callers

nothing calls this directly

Calls 3

FinalRequestOptionsClass · 0.90
startMethod · 0.45
stopMethod · 0.45

Tested by

no test coverage detected