MCPcopy
hub / github.com/openai/openai-python / test_copy_build_request

Method test_copy_build_request

tests/test_client.py:273–333  ·  view source on GitHub ↗
(self, client: OpenAI)

Source from the content-addressed store, hash-verified

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

Callers

nothing calls this directly

Calls 3

FinalRequestOptionsClass · 0.90
startMethod · 0.80
stopMethod · 0.80

Tested by

no test coverage detected