Skip to content

Commit 7001987

Browse files
committed
refactor: move tests to types directory and add copyright headers
1 parent 7b98873 commit 7001987

File tree

3 files changed

+62
-14
lines changed

3 files changed

+62
-14
lines changed

google/genai/tests/models/test_live_client_and_list_type.py renamed to google/genai/tests/types/test_live_client_and_list_type.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
116
"""Tests to verify both LiveClient classes and list[pydantic.BaseModel] support."""
217

318
import inspect
@@ -87,11 +102,11 @@ class Recipe(BaseModel):
87102

88103
def test_combined_functionality(client):
89104
"""Test that combines verification of both LiveClient classes and list[pydantic.BaseModel] support."""
90-
# 1. Verify LiveClient classes exist
105+
# Verify LiveClient classes exist
91106
assert hasattr(types, "LiveClientMessage")
92107
assert inspect.isclass(types.LiveClientMessage)
93108

94-
# 2. Test list[pydantic.BaseModel] support in generate_content
109+
# Test the list[pydantic.BaseModel] support in generate_content
95110
class Recipe(BaseModel):
96111
recipe_name: str
97112
ingredients: List[str]

google/genai/tests/models/test_parsed_list_mypy.py renamed to google/genai/tests/types/test_parsed_list_mypy.py

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
116
"""Tests to verify that mypy correctly handles list[pydantic.BaseModel] in response.parsed."""
217

318
from typing import List, cast
@@ -27,11 +42,11 @@ class Recipe(BaseModel):
2742
# Create a mock response (simulating what we'd get from the API)
2843
response = types.GenerateContentResponse()
2944

30-
# Before the fix, this next line would cause a mypy error:
45+
# Before the fix[issue #886], this next line would cause a mypy error:
3146
# Incompatible types in assignment (expression has type "List[Recipe]",
3247
# variable has type "Optional[Union[BaseModel, Dict[Any, Any], Enum]]")
3348
#
34-
# With our fix adding list[pydantic.BaseModel] to the Union, this is now valid:
49+
# With the fix adding list[pydantic.BaseModel] to the Union, this is now valid:
3550
response.parsed = [
3651
Recipe(
3752
recipe_name="Chocolate Chip Cookies",
@@ -48,16 +63,16 @@ class Recipe(BaseModel):
4863
# and require a cast:
4964
# parsed_items = cast(list[Recipe], response.parsed)
5065

51-
# With our fix, we can directly use it as a list without casting:
66+
# With the fix, we can directly use it as a list without casting:
5267
recipes = response.parsed
5368

54-
# We can iterate over the list without casting
69+
# Now iteration over the list without casting is possible
5570
for recipe in recipes:
5671
logger.info(f"Recipe: {recipe.recipe_name}")
5772
for ingredient in recipe.ingredients:
5873
logger.info(f" - {ingredient}")
5974

60-
# We can access elements by index without casting
75+
# Also accessing elements by index without casting is possible
6176
first_recipe = recipes[0]
6277
logger.info(f"First recipe: {first_recipe.recipe_name}")
6378

@@ -74,12 +89,16 @@ class Recipe(FoodItem):
7489
response = types.GenerateContentResponse()
7590

7691
# Before the fix, this would require a cast with mypy
77-
# Now it works directly with our enhanced type annotation
92+
# Now it works directly with the enhanced type annotation
7893
response.parsed = [
7994
Recipe(
80-
name="Chocolate Chip Cookies", ingredients=["Flour", "Sugar", "Chocolate"]
95+
name="Chocolate Chip Cookies",
96+
ingredients=["Flour", "Sugar", "Chocolate"],
97+
),
98+
Recipe(
99+
name="Oatmeal Cookies",
100+
ingredients=["Oats", "Flour", "Brown Sugar"],
81101
),
82-
Recipe(name="Oatmeal Cookies", ingredients=["Oats", "Flour", "Brown Sugar"]),
83102
]
84103

85104
if response.parsed is not None:
@@ -157,7 +176,7 @@ class Recipe(BaseModel):
157176
]
158177

159178
if response.parsed is not None:
160-
# Before our fix, you'd need this cast for mypy to be happy
179+
# Before the fix, you'd need this cast for mypy to work successfully
161180
recipes = cast(List[Recipe], response.parsed)
162181

163182
# Using the cast list

google/genai/tests/models/test_parsed_list_support.py renamed to google/genai/tests/types/test_parsed_list_support.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
# Copyright 2025 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
116
import sys
217
from enum import Enum
318
from typing import List, Optional, Union
@@ -82,8 +97,7 @@ class Recipe(BaseModel):
8297
recipe_name: str
8398
ingredients: List[str]
8499

85-
# Note: This test is artificial since the model would likely return actual recipes,
86-
# but we're testing the type annotation support, not the model's behavior
100+
# Note: I am only testing the type annotation support, not the model's behavior
87101

88102
# Create a mock response with an empty list
89103
response = types.GenerateContentResponse()
@@ -120,7 +134,7 @@ class Recipe(BaseModel):
120134
# Even if the optional fields are None, the type annotation should work
121135
recipe = response.parsed[0]
122136
assert isinstance(recipe.recipe_name, str)
123-
# Optional fields may or may not be None
137+
124138
assert recipe.prep_time_minutes is None or isinstance(recipe.prep_time_minutes, int)
125139

126140

0 commit comments

Comments
 (0)