From 00d081416feaa34907f87303d2f13743ed479135 Mon Sep 17 00:00:00 2001 From: karpetrosyan Date: Wed, 11 Feb 2026 23:40:54 +0400 Subject: [PATCH 1/6] fix(structured outputs): resolve memory leak in `parse` methods --- src/openai/lib/_parsing/_completions.py | 36 ++++++++++++------------- src/openai/lib/_parsing/_responses.py | 24 +++++++---------- 2 files changed, 28 insertions(+), 32 deletions(-) diff --git a/src/openai/lib/_parsing/_completions.py b/src/openai/lib/_parsing/_completions.py index 7903732a4a..be645a159d 100644 --- a/src/openai/lib/_parsing/_completions.py +++ b/src/openai/lib/_parsing/_completions.py @@ -138,30 +138,30 @@ def parse_chat_completion( choices.append( construct_type_unchecked( - type_=cast(Any, ParsedChoice)[solve_response_format_t(response_format)], + type_=ParsedChoice[ResponseFormatT], value={ **choice.to_dict(), - "message": { - **message.to_dict(), - "parsed": maybe_parse_content( - response_format=response_format, - message=message, - ), - "tool_calls": tool_calls if tool_calls else None, - }, + "message": construct_type_unchecked( + type_=ParsedChatCompletionMessage[ResponseFormatT], + value={ + **message.to_dict(), + "parsed": maybe_parse_content( + response_format=response_format, + message=message, + ), + "tool_calls": tool_calls if tool_calls else None, + }, + ), }, ) ) - return cast( - ParsedChatCompletion[ResponseFormatT], - construct_type_unchecked( - type_=cast(Any, ParsedChatCompletion)[solve_response_format_t(response_format)], - value={ - **chat_completion.to_dict(), - "choices": choices, - }, - ), + return construct_type_unchecked( + type_=ParsedChatCompletion[ResponseFormatT], + value={ + **chat_completion.to_dict(), + "choices": choices, + }, ) diff --git a/src/openai/lib/_parsing/_responses.py b/src/openai/lib/_parsing/_responses.py index 4bed171df7..5676eb0b63 100644 --- a/src/openai/lib/_parsing/_responses.py +++ b/src/openai/lib/_parsing/_responses.py @@ -1,7 +1,7 @@ from __future__ import annotations import json -from typing import TYPE_CHECKING, Any, List, Iterable, cast +from typing import TYPE_CHECKING, List, Iterable, cast from typing_extensions import TypeVar, assert_never import pydantic @@ -12,7 +12,7 @@ from ..._compat import PYDANTIC_V1, model_parse_json from ..._models import construct_type_unchecked from .._pydantic import is_basemodel_type, is_dataclass_like_type -from ._completions import solve_response_format_t, type_to_response_format_param +from ._completions import type_to_response_format_param from ...types.responses import ( Response, ToolParam, @@ -56,7 +56,6 @@ def parse_response( input_tools: Iterable[ToolParam] | Omit | None, response: Response | ParsedResponse[object], ) -> ParsedResponse[TextFormatT]: - solved_t = solve_response_format_t(text_format) output_list: List[ParsedResponseOutputItem[TextFormatT]] = [] for output in response.output: @@ -69,7 +68,7 @@ def parse_response( content_list.append( construct_type_unchecked( - type_=cast(Any, ParsedResponseOutputText)[solved_t], + type_=ParsedResponseOutputText[TextFormatT], value={ **item.to_dict(), "parsed": parse_text(item.text, text_format=text_format), @@ -79,7 +78,7 @@ def parse_response( output_list.append( construct_type_unchecked( - type_=cast(Any, ParsedResponseOutputMessage)[solved_t], + type_=ParsedResponseOutputMessage[TextFormatT], value={ **output.to_dict(), "content": content_list, @@ -123,15 +122,12 @@ def parse_response( else: output_list.append(output) - return cast( - ParsedResponse[TextFormatT], - construct_type_unchecked( - type_=cast(Any, ParsedResponse)[solved_t], - value={ - **response.to_dict(), - "output": output_list, - }, - ), + return construct_type_unchecked( + type_=ParsedResponse[TextFormatT], + value={ + **response.to_dict(), + "output": output_list, + }, ) From d0c242afd0adbb291f43d2712f562696e0697858 Mon Sep 17 00:00:00 2001 From: karpetrosyan Date: Thu, 12 Feb 2026 00:41:05 +0400 Subject: [PATCH 2/6] fix pydantic v1 and v2 conflict in tests snapshots --- tests/lib/chat/test_completions.py | 72 ++++++++++---------- tests/lib/chat/test_completions_streaming.py | 66 +++++++++--------- tests/lib/utils.py | 27 +------- 3 files changed, 71 insertions(+), 94 deletions(-) diff --git a/tests/lib/chat/test_completions.py b/tests/lib/chat/test_completions.py index afad5a1391..85bab4f095 100644 --- a/tests/lib/chat/test_completions.py +++ b/tests/lib/chat/test_completions.py @@ -50,13 +50,13 @@ def test_parse_nothing(client: OpenAI, respx_mock: MockRouter, monkeypatch: pyte assert print_obj(completion, monkeypatch) == snapshot( """\ -ParsedChatCompletion[NoneType]( +ParsedChatCompletion( choices=[ - ParsedChoice[NoneType]( + ParsedChoice( finish_reason='stop', index=0, logprobs=None, - message=ParsedChatCompletionMessage[NoneType]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content="I'm unable to provide real-time weather updates. To get the current weather in San Francisco, I @@ -120,13 +120,13 @@ class Location(BaseModel): assert print_obj(completion, monkeypatch) == snapshot( """\ -ParsedChatCompletion[Location]( +ParsedChatCompletion( choices=[ - ParsedChoice[Location]( + ParsedChoice( finish_reason='stop', index=0, logprobs=None, - message=ParsedChatCompletionMessage[Location]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content='{"city":"San Francisco","temperature":65,"units":"f"}', @@ -191,13 +191,13 @@ class Location(BaseModel): assert print_obj(completion, monkeypatch) == snapshot( """\ -ParsedChatCompletion[Location]( +ParsedChatCompletion( choices=[ - ParsedChoice[Location]( + ParsedChoice( finish_reason='stop', index=0, logprobs=None, - message=ParsedChatCompletionMessage[Location]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content='{"city":"San Francisco","temperature":65,"units":"f"}', @@ -266,11 +266,11 @@ class ColorDetection(BaseModel): assert print_obj(completion.choices[0], monkeypatch) == snapshot( """\ -ParsedChoice[ColorDetection]( +ParsedChoice( finish_reason='stop', index=0, logprobs=None, - message=ParsedChatCompletionMessage[ColorDetection]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content='{"color":"red","hex_color_code":"#FF0000"}', @@ -317,11 +317,11 @@ class Location(BaseModel): assert print_obj(completion.choices, monkeypatch) == snapshot( """\ [ - ParsedChoice[Location]( + ParsedChoice( finish_reason='stop', index=0, logprobs=None, - message=ParsedChatCompletionMessage[Location]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content='{"city":"San Francisco","temperature":64,"units":"f"}', @@ -332,11 +332,11 @@ class Location(BaseModel): tool_calls=None ) ), - ParsedChoice[Location]( + ParsedChoice( finish_reason='stop', index=1, logprobs=None, - message=ParsedChatCompletionMessage[Location]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content='{"city":"San Francisco","temperature":65,"units":"f"}', @@ -347,11 +347,11 @@ class Location(BaseModel): tool_calls=None ) ), - ParsedChoice[Location]( + ParsedChoice( finish_reason='stop', index=2, logprobs=None, - message=ParsedChatCompletionMessage[Location]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content='{"city":"San Francisco","temperature":63.0,"units":"f"}', @@ -397,13 +397,13 @@ class CalendarEvent: assert print_obj(completion, monkeypatch) == snapshot( """\ -ParsedChatCompletion[CalendarEvent]( +ParsedChatCompletion( choices=[ - ParsedChoice[CalendarEvent]( + ParsedChoice( finish_reason='stop', index=0, logprobs=None, - message=ParsedChatCompletionMessage[CalendarEvent]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content='{"name":"Science Fair","date":"Friday","participants":["Alice","Bob"]}', @@ -462,11 +462,11 @@ def test_pydantic_tool_model_all_types(client: OpenAI, respx_mock: MockRouter, m assert print_obj(completion.choices[0], monkeypatch) == snapshot( """\ -ParsedChoice[Query]( +ParsedChoice( finish_reason='tool_calls', index=0, logprobs=None, - message=ParsedChatCompletionMessage[Query]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content=None, @@ -576,11 +576,11 @@ class Location(BaseModel): assert print_obj(completion.choices, monkeypatch) == snapshot( """\ [ - ParsedChoice[Location]( + ParsedChoice( finish_reason='stop', index=0, logprobs=None, - message=ParsedChatCompletionMessage[Location]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content=None, @@ -627,11 +627,11 @@ class GetWeatherArgs(BaseModel): assert print_obj(completion.choices, monkeypatch) == snapshot( """\ [ - ParsedChoice[NoneType]( + ParsedChoice( finish_reason='tool_calls', index=0, logprobs=None, - message=ParsedChatCompletionMessage[NoneType]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content=None, @@ -701,11 +701,11 @@ class GetStockPrice(BaseModel): assert print_obj(completion.choices, monkeypatch) == snapshot( """\ [ - ParsedChoice[NoneType]( + ParsedChoice( finish_reason='tool_calls', index=0, logprobs=None, - message=ParsedChatCompletionMessage[NoneType]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content=None, @@ -784,11 +784,11 @@ def test_parse_strict_tools(client: OpenAI, respx_mock: MockRouter, monkeypatch: assert print_obj(completion.choices, monkeypatch) == snapshot( """\ [ - ParsedChoice[NoneType]( + ParsedChoice( finish_reason='tool_calls', index=0, logprobs=None, - message=ParsedChatCompletionMessage[NoneType]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content=None, @@ -866,13 +866,13 @@ class Location(BaseModel): assert isinstance(message.parsed.city, str) assert print_obj(completion, monkeypatch) == snapshot( """\ -ParsedChatCompletion[Location]( +ParsedChatCompletion( choices=[ - ParsedChoice[Location]( + ParsedChoice( finish_reason='stop', index=0, logprobs=None, - message=ParsedChatCompletionMessage[Location]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content='{"city":"San Francisco","temperature":58,"units":"f"}', @@ -943,13 +943,13 @@ class Location(BaseModel): assert isinstance(message.parsed.city, str) assert print_obj(completion, monkeypatch) == snapshot( """\ -ParsedChatCompletion[Location]( +ParsedChatCompletion( choices=[ - ParsedChoice[Location]( + ParsedChoice( finish_reason='stop', index=0, logprobs=None, - message=ParsedChatCompletionMessage[Location]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content='{"city":"San Francisco","temperature":65,"units":"f"}', diff --git a/tests/lib/chat/test_completions_streaming.py b/tests/lib/chat/test_completions_streaming.py index 548416dfe2..eb3a0973ac 100644 --- a/tests/lib/chat/test_completions_streaming.py +++ b/tests/lib/chat/test_completions_streaming.py @@ -63,11 +63,11 @@ def test_parse_nothing(client: OpenAI, respx_mock: MockRouter, monkeypatch: pyte assert print_obj(listener.stream.get_final_completion().choices, monkeypatch) == snapshot( """\ [ - ParsedChoice[NoneType]( + ParsedChoice( finish_reason='stop', index=0, logprobs=None, - message=ParsedChatCompletionMessage[NoneType]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content="I'm unable to provide real-time weather updates. To get the current weather in San Francisco, I @@ -84,7 +84,7 @@ def test_parse_nothing(client: OpenAI, respx_mock: MockRouter, monkeypatch: pyte ) assert print_obj(listener.get_event_by_type("content.done"), monkeypatch) == snapshot( """\ -ContentDoneEvent[NoneType]( +ContentDoneEvent( content="I'm unable to provide real-time weather updates. To get the current weather in San Francisco, I recommend checking a reliable weather website or a weather app.", parsed=None, @@ -140,13 +140,13 @@ def on_event(stream: ChatCompletionStream[Location], event: ChatCompletionStream assert print_obj(listener.stream.get_final_completion(), monkeypatch) == snapshot( """\ -ParsedChatCompletion[Location]( +ParsedChatCompletion( choices=[ - ParsedChoice[Location]( + ParsedChoice( finish_reason='stop', index=0, logprobs=None, - message=ParsedChatCompletionMessage[Location]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content='{"city":"San Francisco","temperature":61,"units":"f"}', @@ -181,7 +181,7 @@ def on_event(stream: ChatCompletionStream[Location], event: ChatCompletionStream ) assert print_obj(listener.get_event_by_type("content.done"), monkeypatch) == snapshot( """\ -ContentDoneEvent[Location]( +ContentDoneEvent( content='{"city":"San Francisco","temperature":61,"units":"f"}', parsed=Location(city='San Francisco', temperature=61.0, units='f'), type='content.done' @@ -320,11 +320,11 @@ class Location(BaseModel): assert print_obj(listener.stream.get_final_completion().choices, monkeypatch) == snapshot( """\ [ - ParsedChoice[Location]( + ParsedChoice( finish_reason='stop', index=0, logprobs=None, - message=ParsedChatCompletionMessage[Location]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content='{"city":"San Francisco","temperature":65,"units":"f"}', @@ -335,11 +335,11 @@ class Location(BaseModel): tool_calls=None ) ), - ParsedChoice[Location]( + ParsedChoice( finish_reason='stop', index=1, logprobs=None, - message=ParsedChatCompletionMessage[Location]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content='{"city":"San Francisco","temperature":61,"units":"f"}', @@ -350,11 +350,11 @@ class Location(BaseModel): tool_calls=None ) ), - ParsedChoice[Location]( + ParsedChoice( finish_reason='stop', index=2, logprobs=None, - message=ParsedChatCompletionMessage[Location]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content='{"city":"San Francisco","temperature":59,"units":"f"}', @@ -426,11 +426,11 @@ class Location(BaseModel): assert print_obj(listener.stream.get_final_completion().choices, monkeypatch) == snapshot( """\ [ - ParsedChoice[Location]( + ParsedChoice( finish_reason='stop', index=0, logprobs=None, - message=ParsedChatCompletionMessage[Location]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content=None, @@ -495,7 +495,7 @@ def test_content_logprobs_events(client: OpenAI, respx_mock: MockRouter, monkeyp assert print_obj(listener.stream.get_final_completion().choices, monkeypatch) == snapshot("""\ [ - ParsedChoice[NoneType]( + ParsedChoice( finish_reason='stop', index=0, logprobs=ChoiceLogprobs( @@ -505,7 +505,7 @@ def test_content_logprobs_events(client: OpenAI, respx_mock: MockRouter, monkeyp ], refusal=None ), - message=ParsedChatCompletionMessage[NoneType]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content='Foo!', @@ -563,7 +563,7 @@ class Location(BaseModel): assert print_obj(listener.stream.get_final_completion().choices, monkeypatch) == snapshot("""\ [ - ParsedChoice[Location]( + ParsedChoice( finish_reason='stop', index=0, logprobs=ChoiceLogprobs( @@ -617,7 +617,7 @@ class Location(BaseModel): ChatCompletionTokenLogprob(bytes=[46], logprob=-0.57687104, token='.', top_logprobs=[]) ] ), - message=ParsedChatCompletionMessage[Location]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content=None, @@ -660,11 +660,11 @@ class GetWeatherArgs(BaseModel): assert print_obj(listener.stream.current_completion_snapshot.choices, monkeypatch) == snapshot( """\ [ - ParsedChoice[object]( + ParsedChoice( finish_reason='tool_calls', index=0, logprobs=None, - message=ParsedChatCompletionMessage[object]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content=None, @@ -693,11 +693,11 @@ class GetWeatherArgs(BaseModel): assert print_obj(listener.stream.get_final_completion().choices, monkeypatch) == snapshot( """\ [ - ParsedChoice[NoneType]( + ParsedChoice( finish_reason='tool_calls', index=0, logprobs=None, - message=ParsedChatCompletionMessage[NoneType]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content=None, @@ -765,11 +765,11 @@ class GetStockPrice(BaseModel): assert print_obj(listener.stream.current_completion_snapshot.choices, monkeypatch) == snapshot( """\ [ - ParsedChoice[object]( + ParsedChoice( finish_reason='tool_calls', index=0, logprobs=None, - message=ParsedChatCompletionMessage[object]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content=None, @@ -874,11 +874,11 @@ def test_parse_strict_tools(client: OpenAI, respx_mock: MockRouter, monkeypatch: assert print_obj(listener.stream.current_completion_snapshot.choices, monkeypatch) == snapshot( """\ [ - ParsedChoice[object]( + ParsedChoice( finish_reason='tool_calls', index=0, logprobs=None, - message=ParsedChatCompletionMessage[object]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content=None, @@ -926,11 +926,11 @@ def test_non_pydantic_response_format(client: OpenAI, respx_mock: MockRouter, mo assert print_obj(listener.stream.get_final_completion().choices, monkeypatch) == snapshot( """\ [ - ParsedChoice[NoneType]( + ParsedChoice( finish_reason='stop', index=0, logprobs=None, - message=ParsedChatCompletionMessage[NoneType]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content='\\n {\\n "location": "San Francisco, CA",\\n "weather": {\\n "temperature": "18°C",\\n @@ -987,11 +987,11 @@ def test_allows_non_strict_tools_but_no_parsing( assert print_obj(listener.stream.get_final_completion().choices, monkeypatch) == snapshot( """\ [ - ParsedChoice[NoneType]( + ParsedChoice( finish_reason='tool_calls', index=0, logprobs=None, - message=ParsedChatCompletionMessage[NoneType]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content=None, @@ -1047,11 +1047,11 @@ def streamer(client: OpenAI) -> Iterator[ChatCompletionChunk]: assert print_obj(state.get_final_completion().choices, monkeypatch) == snapshot( """\ [ - ParsedChoice[NoneType]( + ParsedChoice( finish_reason='stop', index=0, logprobs=None, - message=ParsedChatCompletionMessage[NoneType]( + message=ParsedChatCompletionMessage( annotations=None, audio=None, content="I'm unable to provide real-time weather updates. To get the current weather in San Francisco, I diff --git a/tests/lib/utils.py b/tests/lib/utils.py index e6b6a29434..f2ae6469f3 100644 --- a/tests/lib/utils.py +++ b/tests/lib/utils.py @@ -1,6 +1,6 @@ from __future__ import annotations -import inspect +import re from typing import Any, Iterable from typing_extensions import TypeAlias @@ -28,27 +28,4 @@ def __repr_args__(self: pydantic.BaseModel) -> ReprArgs: string = rich_print_str(obj) - # we remove all `fn_name..` occurrences - # so that we can share the same snapshots between - # pydantic v1 and pydantic v2 as their output for - # generic models differs, e.g. - # - # v2: `ParsedChatCompletion[test_parse_pydantic_model..Location]` - # v1: `ParsedChatCompletion[Location]` - return clear_locals(string, stacklevel=2) - - -def get_caller_name(*, stacklevel: int = 1) -> str: - frame = inspect.currentframe() - assert frame is not None - - for i in range(stacklevel): - frame = frame.f_back - assert frame is not None, f"no {i}th frame" - - return frame.f_code.co_name - - -def clear_locals(string: str, *, stacklevel: int) -> str: - caller = get_caller_name(stacklevel=stacklevel + 1) - return string.replace(f"{caller}..", "") + return re.sub(r"([A-Za-z_]\w*)\[[^\[\]]+\](?=\()", r"\1", string) From b78e7f7358792e897f984d587fafd6a27e0504e3 Mon Sep 17 00:00:00 2001 From: karpetrosyan Date: Thu, 12 Feb 2026 01:25:22 +0400 Subject: [PATCH 3/6] remove redundant construct_type_unchecked call --- src/openai/lib/_parsing/_completions.py | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/openai/lib/_parsing/_completions.py b/src/openai/lib/_parsing/_completions.py index be645a159d..bb16368f4a 100644 --- a/src/openai/lib/_parsing/_completions.py +++ b/src/openai/lib/_parsing/_completions.py @@ -141,17 +141,14 @@ def parse_chat_completion( type_=ParsedChoice[ResponseFormatT], value={ **choice.to_dict(), - "message": construct_type_unchecked( - type_=ParsedChatCompletionMessage[ResponseFormatT], - value={ - **message.to_dict(), - "parsed": maybe_parse_content( - response_format=response_format, - message=message, - ), - "tool_calls": tool_calls if tool_calls else None, - }, - ), + "message": { + **message.to_dict(), + "parsed": maybe_parse_content( + response_format=response_format, + message=message, + ), + "tool_calls": tool_calls if tool_calls else None, + }, }, ) ) From 38fd4d4a1d9df76271f0a494213eb83dd918c2b2 Mon Sep 17 00:00:00 2001 From: karpetrosyan Date: Thu, 12 Feb 2026 15:14:11 +0400 Subject: [PATCH 4/6] explain the re.sub --- tests/lib/utils.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/lib/utils.py b/tests/lib/utils.py index f2ae6469f3..0efdfca968 100644 --- a/tests/lib/utils.py +++ b/tests/lib/utils.py @@ -28,4 +28,7 @@ def __repr_args__(self: pydantic.BaseModel) -> ReprArgs: string = rich_print_str(obj) + # Pydantic v1 and v2 have different implementations of __repr__ and print out + # generics differently, so we strip out generic type parameters to ensure + # consistent snapshot tests across both versions return re.sub(r"([A-Za-z_]\w*)\[[^\[\]]+\](?=\()", r"\1", string) From 933bebe6544d9a85b0ab4768a5889e499da7aec6 Mon Sep 17 00:00:00 2001 From: karpetrosyan Date: Thu, 12 Feb 2026 15:28:24 +0400 Subject: [PATCH 5/6] fix leak for streaming too --- src/openai/lib/_parsing/_completions.py | 14 -------------- src/openai/lib/streaming/chat/_completions.py | 3 +-- 2 files changed, 1 insertion(+), 16 deletions(-) diff --git a/src/openai/lib/_parsing/_completions.py b/src/openai/lib/_parsing/_completions.py index bb16368f4a..7a1bded1de 100644 --- a/src/openai/lib/_parsing/_completions.py +++ b/src/openai/lib/_parsing/_completions.py @@ -198,20 +198,6 @@ def maybe_parse_content( return None -def solve_response_format_t( - response_format: type[ResponseFormatT] | ResponseFormatParam | Omit, -) -> type[ResponseFormatT]: - """Return the runtime type for the given response format. - - If no response format is given, or if we won't auto-parse the response format - then we default to `None`. - """ - if has_rich_response_format(response_format): - return response_format - - return cast("type[ResponseFormatT]", _default_response_format) - - def has_parseable_input( *, response_format: type | ResponseFormatParam | Omit, diff --git a/src/openai/lib/streaming/chat/_completions.py b/src/openai/lib/streaming/chat/_completions.py index c4610e2120..5f072cafbd 100644 --- a/src/openai/lib/streaming/chat/_completions.py +++ b/src/openai/lib/streaming/chat/_completions.py @@ -33,7 +33,6 @@ maybe_parse_content, parse_chat_completion, get_input_tool_by_name, - solve_response_format_t, parse_function_tool_arguments, ) from ...._streaming import Stream, AsyncStream @@ -663,7 +662,7 @@ def _content_done_events( # type variable, e.g. `ContentDoneEvent[MyModelType]` cast( # pyright: ignore[reportUnnecessaryCast] "type[ContentDoneEvent[ResponseFormatT]]", - cast(Any, ContentDoneEvent)[solve_response_format_t(response_format)], + cast(Any, ContentDoneEvent), ), type="content.done", content=choice_snapshot.message.content, From 3d7f0aa24814c17b2ca12ff7b8079c78b0f811f1 Mon Sep 17 00:00:00 2001 From: karpetrosyan Date: Thu, 12 Feb 2026 15:29:48 +0400 Subject: [PATCH 6/6] fix lint --- src/openai/lib/_parsing/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/openai/lib/_parsing/__init__.py b/src/openai/lib/_parsing/__init__.py index 4d454c3a20..08591f43f4 100644 --- a/src/openai/lib/_parsing/__init__.py +++ b/src/openai/lib/_parsing/__init__.py @@ -6,7 +6,6 @@ validate_input_tools as validate_input_tools, parse_chat_completion as parse_chat_completion, get_input_tool_by_name as get_input_tool_by_name, - solve_response_format_t as solve_response_format_t, parse_function_tool_arguments as parse_function_tool_arguments, type_to_response_format_param as type_to_response_format_param, )