From 7377b16036b2b579455291b791c68cd3e23206a8 Mon Sep 17 00:00:00 2001 From: Ishaan Samantray Date: Mon, 1 Jun 2026 15:37:38 -0400 Subject: [PATCH] fix(_transform): guard against IndexError on bare dict annotation get_args(dict) returns an empty tuple, so the unconditional [1] index in _transform_recursive (and its async counterpart) raised IndexError whenever a mapping value was passed against an un-parameterised dict type annotation. Add a bounds check and fall through to the data as-is when no type args are present. --- src/groq/_utils/_transform.py | 10 ++++++++-- tests/test_transform.py | 9 +++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/groq/_utils/_transform.py b/src/groq/_utils/_transform.py index 52075492..f70b4b6a 100644 --- a/src/groq/_utils/_transform.py +++ b/src/groq/_utils/_transform.py @@ -180,7 +180,10 @@ def _transform_recursive( return _transform_typeddict(data, stripped_type) if origin == dict and is_mapping(data): - items_type = get_args(stripped_type)[1] + args = get_args(stripped_type) + if not args: + return data + items_type = args[1] return {key: _transform_recursive(value, annotation=items_type) for key, value in data.items()} if ( @@ -346,7 +349,10 @@ async def _async_transform_recursive( return await _async_transform_typeddict(data, stripped_type) if origin == dict and is_mapping(data): - items_type = get_args(stripped_type)[1] + args = get_args(stripped_type) + if not args: + return data + items_type = args[1] return {key: _transform_recursive(value, annotation=items_type) for key, value in data.items()} if ( diff --git a/tests/test_transform.py b/tests/test_transform.py index affc3eeb..8807fa08 100644 --- a/tests/test_transform.py +++ b/tests/test_transform.py @@ -453,6 +453,15 @@ async def test_strips_notgiven(use_async: bool) -> None: assert await transform({"foo_bar": not_given}, Foo1, use_async) == {} +@parametrize +@pytest.mark.asyncio +async def test_bare_dict_annotation_no_indexerror(use_async: bool) -> None: + # A bare `dict` annotation (no type args) previously raised IndexError because + # get_args(dict) returns () and the code unconditionally indexed [1]. + result = await transform({"key": {"a": 1}}, Annotated[dict, PropertyInfo(alias="key")], use_async) + assert result == {"key": {"a": 1}} + + @parametrize @pytest.mark.asyncio async def test_strips_omit(use_async: bool) -> None: