From ea47daf11c23e364419a6a9934516d1a5f15b918 Mon Sep 17 00:00:00 2001 From: lrg913427-dot Date: Mon, 1 Jun 2026 22:18:23 +0800 Subject: [PATCH] fix: handle bare dict annotation in construct_type() When type_ is a bare dict without type parameters (e.g. dict instead of dict[str, Any]), get_args(dict) returns an empty tuple. The previous code unconditionally unpacked two values from it, causing ValueError. Add a length check before unpacking and return the value as-is for bare dicts since there are no type parameters to recurse into. Fixes #3341 --- src/openai/_models.py | 7 ++++++- tests/test_models.py | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/openai/_models.py b/src/openai/_models.py index ed4c1f82d6..03a99729a5 100644 --- a/src/openai/_models.py +++ b/src/openai/_models.py @@ -657,7 +657,12 @@ def construct_type(*, value: object, type_: object, metadata: Optional[List[Any] if not is_mapping(value): return value - _, items_type = get_args(type_) # Dict[_, items_type] + args = get_args(type_) + if len(args) < 2: + # bare `dict` with no type parameters (e.g. `dict` instead of + # `dict[str, Any]`) — nothing to recurse into, return as-is. + return value + _, items_type = args return {key: construct_type(value=item, type_=items_type) for key, item in value.items()} if ( diff --git a/tests/test_models.py b/tests/test_models.py index cc204bac1d..10ca835628 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -133,6 +133,22 @@ class NestedModel(BaseModel): assert cast(Any, m.nested) is False + +def test_bare_dict_annotation() -> None: + """construct_type should not crash on bare dict annotations without type parameters.""" + # This was crashing with ValueError: not enough values to unpack + # because get_args(dict) returns () for unparameterised dict. + result = construct_type(value={"key": "value"}, type_=dict) + assert result == {"key": "value"} + + result = construct_type(value={"a": 1, "b": 2}, type_=dict) + assert result == {"a": 1, "b": 2} + + # empty dict + result = construct_type(value={}, type_=dict) + assert result == {} + + def test_nested_dictionary_model() -> None: class NestedModel(BaseModel): nested: Dict[str, BasicModel]