fix: handles function tool parsing corner case where type hints are stored as strings.

Previously if you add `from __future__ import annotations` in your code, the parsing code would fail because the type hints will be a string instead of the class itself (e.g. input: 'str' instead of input: str).

Also added "_" to the util file name.

PiperOrigin-RevId: 764817339
This commit is contained in:
Liang Wu 2025-05-29 11:38:41 -07:00 committed by Copybara-Service
parent d587270327
commit a8a20743f9
2 changed files with 21 additions and 9 deletions

View File

@ -16,6 +16,7 @@ from __future__ import annotations
import inspect import inspect
from types import FunctionType from types import FunctionType
import typing
from typing import Any from typing import Any
from typing import Callable from typing import Callable
from typing import Dict from typing import Dict
@ -29,7 +30,7 @@ from pydantic import BaseModel
from pydantic import create_model from pydantic import create_model
from pydantic import fields as pydantic_fields from pydantic import fields as pydantic_fields
from . import function_parameter_parse_util from . import _function_parameter_parse_util
_py_type_2_schema_type = { _py_type_2_schema_type = {
'str': types.Type.STRING, 'str': types.Type.STRING,
@ -306,7 +307,11 @@ def from_function_with_options(
inspect.Parameter.KEYWORD_ONLY, inspect.Parameter.KEYWORD_ONLY,
inspect.Parameter.POSITIONAL_ONLY, inspect.Parameter.POSITIONAL_ONLY,
): ):
schema = function_parameter_parse_util._parse_schema_from_parameter( # This snippet catches the case when type hints are stored as strings
if isinstance(param.annotation, str):
param = param.replace(annotation=typing.get_type_hints(func)[name])
schema = _function_parameter_parse_util._parse_schema_from_parameter(
variant, param, func.__name__ variant, param, func.__name__
) )
parameters_properties[name] = schema parameters_properties[name] = schema
@ -320,7 +325,7 @@ def from_function_with_options(
properties=parameters_properties, properties=parameters_properties,
) )
declaration.parameters.required = ( declaration.parameters.required = (
function_parameter_parse_util._get_required_fields( _function_parameter_parse_util._get_required_fields(
declaration.parameters declaration.parameters
) )
) )
@ -331,14 +336,19 @@ def from_function_with_options(
if return_annotation is inspect._empty: if return_annotation is inspect._empty:
return declaration return declaration
return_value = inspect.Parameter(
'return_value',
inspect.Parameter.POSITIONAL_OR_KEYWORD,
annotation=return_annotation,
)
# This snippet catches the case when type hints are stored as strings
if isinstance(return_value.annotation, str):
return_value = return_value.replace(annotation=typing.get_type_hints(func)["return"])
declaration.response = ( declaration.response = (
function_parameter_parse_util._parse_schema_from_parameter( _function_parameter_parse_util._parse_schema_from_parameter(
variant, variant,
inspect.Parameter( return_value,
'return_value',
inspect.Parameter.POSITIONAL_OR_KEYWORD,
annotation=return_annotation,
),
func.__name__, func.__name__,
) )
) )

View File

@ -13,6 +13,8 @@
# limitations under the License. # limitations under the License.
# #
from __future__ import annotations
import inspect import inspect
import logging import logging
import types as typing_types import types as typing_types