-
Notifications
You must be signed in to change notification settings - Fork 754
Description
Description
When automatic function calling processes a function with a parameterized generic type annotation (e.g., set[str]), the SDK raises TypeError: isinstance() argument 2 cannot be a parameterized generic.
Note
Apologies, my agent posted before I got to review this, but it seems mostly fine.
Minimal Reproduction
from google.genai._extra_utils import convert_if_exist_pydantic_model
# Simulating what happens when Gemini returns a value for a set[str] parameter
result = convert_if_exist_pydantic_model(
value=['a', 'b'], # Gemini returns list (JSON array)
annotation=set[str], # But annotation is set[str]
param_name='items',
func_name='my_func'
)
# TypeError: isinstance() argument 2 cannot be a parameterized genericCause
In _extra_utils.py, the function convert_if_exist_pydantic_model() has two locations where isinstance() is called with an annotation that could be a GenericAlias:
Line 257 (inside Union handling):
or isinstance(value, arg)Line 279 (final fallback):
if not isinstance(value, annotation):In Python, isinstance(x, set[str]) raises TypeError because set[str] is a GenericAlias, not a type. The SDK correctly handles list[T] and dict[K,V] with special cases using get_origin(), but other parameterized generics fall through to the raw isinstance() call.
Affected Versions
- google-genai 1.60.0
- google-genai 1.61.0
Environment
- Python 3.12
- Linux
Proposed Fix
Add a helper function that safely handles parameterized generics:
def _safe_isinstance(value: Any, annotation: Any) -> bool:
"""Check isinstance, handling GenericAlias types like set[str]."""
origin = get_origin(annotation)
if origin is not None:
return isinstance(value, origin)
try:
return isinstance(value, annotation)
except TypeError:
return FalseThen replace:
- Line 257:
isinstance(value, arg)→_safe_isinstance(value, arg) - Line 279:
isinstance(value, annotation)→_safe_isinstance(value, annotation)
This follows the same pattern already used for list[T] and dict[K,V] at lines 239 and 245.