Repository navigation
fix: convert iterators to list in t_contents to avoid confusing errors - #3212
yashdhumane wants to merge 3 commits into
Conversation
Passing a reversed() iterator or any non-list iterable to generate_content caused confusing errors like 'contents are required' or 'file uri and mime_type are required' instead of a clear message. Fix converts iterables (generators, reversed, map, etc.) to a list before validation, so they work correctly. Fixes googleapis#1272
chrikrah
left a comment
There was a problem hiding this comment.
@yashdhumane this breaks a single Part or File passed as contents, and #1272 still fails through generate_content. Pydantic models define __iter__, so list(contents) yields (field, value) tuples. And _GenerateContentParameters validates contents before t_contents runs, which turns reversed([...]) into [File()].
blocking: materialize an iterator in generate_content and generate_content_stream, sync and async, before the parameter model is built, or raise a TypeError there. The t_contents line can then go, which also clears the red mypy (3.11) check.
# probe: client.models.generate_content(model="gemini-2.5-flash", contents=x), _api_client.request mocked
# CPython 3.12.6, pydantic 2.12.0, google.genai imported from trees exported with git archive
base c0e9c54 head f7f459d
reversed([Content]) ValueError: file uri and mime_type ... ValueError: file uri and mime_type ...
generator of Content ValueError: file uri and mime_type ... ValueError: file uri and mime_type ...
Part(text="hi") ok, 1 content sent ValueError: Unsupported content type: <class 'tuple'>
$ python -m pytest google/genai/tests/transformers -q -p no:cacheprovider
181 passed in 6.15s # base c0e9c54
1 failed, 180 passed in 6.13s # head f7f459d, test_file
$ mypy google/genai/ # mypy 2.4.0, CPython 3.11
Success: no issues found in 41 source files # base c0e9c54
Found 1 error in 1 file (checked 41 source files) # head f7f459d, _transformers.py:477 arg-type on list(contents)
# not run: the replay tests and anything outside tests/transformers
Could the #1272 test call generate_content with a mocked request, where it fails today?
|
Thank you for the detailed analysis and the probe script — you were completely right. The Updated fix:
|
chrikrah
left a comment
There was a problem hiding this comment.
@yashdhumane 1754f71 sends an iterator whole on all four paths, and a single Part works again. From my perspective this can be merged. It does accept more than ContentListUnion, which still says list, so mypy flags reversed(...); widening the generated annotation is a maintainer call.
# probe: generate_content(contents=x) with _api_client request methods stubbed; Python 3.12, pydantic 2.12.0, trees from git archive
base c0e9c54 head 1754f71
reversed([Content, Content]) ValueError: file uri and mime... sync, stream, async, astream: 2 contents sent
generator of Content ValueError: file uri and mime... sync, stream, async, astream: 2 contents sent
Part(text="hi") 1 content sent 1 content sent
$ mypy google/genai/ # mypy 2.4.0, CPython 3.11, head 1754f71
Success: no issues found in 41 source files
$ python -m pytest google/genai/tests/transformers google/genai/tests/models/test_gc_continuation_token.py -q -p no:cacheprovider
215 passed # head 1754f71
215 passed # base c0e9c54
non-blocking: the _transformers.py hunk is now a lone trailing blank line, and the title still names t_contents. No test tells the two commits apart, as the last two lines show. Can you add a mocked reversed([...]) case to test_gc_continuation_token.py?
|
Added mocked reversed([...]) test case to test_gc_continuation_token.py and removed the trailing blank line from _transformers.py. 35 tests pass on Python 3.12. |
Passing a reversed() iterator or any non-list iterable to generate_content caused confusing errors like 'contents are required' or 'file uri and mime_type are required' instead of a clear message.
Fix converts iterables (generators, reversed, map, etc.) to a list before validation, so they work correctly.
Fixes #1272