chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:17:40 +08:00
commit f1825c8ceb
10096 changed files with 2364182 additions and 0 deletions
@@ -0,0 +1,293 @@
"""Type checking tests for DeploymentHandle, DeploymentResponse, and DeploymentResponseGenerator.
This file is used with mypy to verify that the generic type annotations
on handle classes work correctly. Run with:
mypy python/ray/serve/tests/typing_files/check_handle_typing.py python/ray/serve/handle.py \
--follow-imports=skip \
--ignore-missing-imports
mypy will fail if any assert_type() call doesn't match the expected type.
"""
from typing import Any, AsyncIterator, Iterator, Union
from typing_extensions import assert_type
from ray.serve.handle import (
DeploymentBroadcastResponse,
DeploymentHandle,
DeploymentResponse,
DeploymentResponseGenerator,
)
def test_deployment_response_types() -> None:
"""Test that DeploymentResponse[R] preserves R through methods."""
response: DeploymentResponse[str] = None # type: ignore[assignment]
# result() should return R (str)
result = response.result()
assert_type(result, str)
# Properties should work
assert_type(response.request_id, str)
assert_type(response.by_reference, bool)
async def test_deployment_response_await() -> None:
"""Test that awaiting DeploymentResponse[R] returns R."""
response: DeploymentResponse[str] = None # type: ignore[assignment]
# Awaiting should return R (str)
awaited_result = await response
assert_type(awaited_result, str)
async def test_broadcast_response_types() -> None:
"""Test DeploymentBroadcastResponse typing behavior."""
response: DeploymentBroadcastResponse = None # type: ignore[assignment]
sync_results = response.results()
assert_type(sync_results, list[Any])
async_results = await response.results_async()
assert_type(async_results, list[Any])
def test_deployment_response_generator_sync() -> None:
"""Test that DeploymentResponseGenerator[R] iteration returns R."""
gen: DeploymentResponseGenerator[int] = None # type: ignore[assignment]
# __iter__ should return Iterator[R]
assert_type(iter(gen), Iterator[int])
# __next__ should return R (int)
item = next(gen)
assert_type(item, int)
# For loop iteration
for value in gen:
assert_type(value, int)
break
async def test_deployment_response_generator_async() -> None:
"""Test that async iteration of DeploymentResponseGenerator[R] returns R."""
gen: DeploymentResponseGenerator[int] = None # type: ignore[assignment]
# __aiter__ should return AsyncIterator[R]
assert_type(gen.__aiter__(), AsyncIterator[int])
# __anext__ should return R (int)
item = await gen.__anext__()
assert_type(item, int)
# Async for loop iteration
async for value in gen:
assert_type(value, int)
break
def test_deployment_handle_types() -> None:
"""Test DeploymentHandle type annotations."""
class MyDeployment:
def get_string(self) -> str:
return "hello"
def get_int(self) -> int:
return 42
handle: DeploymentHandle[MyDeployment] = None # type: ignore[assignment]
# Basic properties
assert_type(handle.deployment_name, str)
assert_type(handle.app_name, str)
assert_type(handle.is_initialized, bool)
# options() should return DeploymentHandle[T]
new_handle = handle.options(method_name="get_string")
assert_type(new_handle, DeploymentHandle[MyDeployment])
# remote() returns Union[DeploymentResponse[Any], DeploymentResponseGenerator[Any]]
# (until plugin is implemented to infer the actual return type)
response = handle.remote()
assert_type(
response,
Union[DeploymentResponse[Any], DeploymentResponseGenerator[Any]],
)
broadcast_response = handle.broadcast("get_string")
assert_type(broadcast_response, DeploymentBroadcastResponse)
assert_type(broadcast_response.results(), list[Any])
def test_chained_handle_access() -> None:
"""Test that accessing methods on handle returns typed handle."""
class MyDeployment:
def my_method(self, x: int) -> str:
return str(x)
handle: DeploymentHandle[MyDeployment] = None # type: ignore[assignment]
# Accessing a method via __getattr__ should return DeploymentHandle[T]
method_handle = handle.my_method
assert_type(method_handle, DeploymentHandle[MyDeployment])
# =============================================================================
# TESTS THAT REQUIRE MYPY PLUGIN
# =============================================================================
# The following tests verify that the mypy plugin correctly infers return types
# based on which deployment method is being called. These tests are commented
# out because they will fail without the plugin.
#
# To enable after plugin is implemented:
# 1. Uncomment the tests below
# 2. Run: mypy python/ray/serve/tests/typing_files/check_handle_typing.py
# 3. All assert_type() calls should pass
# =============================================================================
def test_plugin_infers_method_return_type() -> None:
"""[REQUIRES PLUGIN] Test that remote() infers return type from method."""
from typing import Generator
class MyDeployment:
def get_user(self, user_id: int) -> str:
return f"user_{user_id}"
def get_count(self) -> int:
return 42
def stream_items(self) -> Generator[bytes, None, None]:
yield b"chunk1"
yield b"chunk2"
_: DeploymentHandle[MyDeployment] = None # type: ignore[assignment]
# # Calling a method that returns str should give DeploymentResponse[str]
# response_str = handle.get_user.remote(123)
# assert_type(response_str, DeploymentResponse[str])
# # result() should return str
# user = response_str.result()
# assert_type(user, str)
# # Calling a method that returns int should give DeploymentResponse[int]
# response_int = handle.get_count.remote()
# assert_type(response_int, DeploymentResponse[int])
# # result() should return int
# count = response_int.result()
# assert_type(count, int)
async def test_plugin_infers_await_return_type() -> None:
"""[REQUIRES PLUGIN] Test that await infers return type from method."""
class MyDeployment:
def process(self, data: str) -> dict:
return {"data": data}
_: DeploymentHandle[MyDeployment] = None # type: ignore[assignment]
# response = handle.process.remote("test")
# assert_type(response, DeploymentResponse[dict])
# # Awaiting should return dict
# result = await response
# assert_type(result, dict)
def test_plugin_infers_generator_yield_type() -> None:
"""[REQUIRES PLUGIN] Test that streaming methods infer yield type."""
from typing import Generator
class MyDeployment:
def stream_strings(self) -> Generator[str, None, None]:
yield "a"
yield "b"
def stream_ints(self) -> Generator[int, None, None]:
yield 1
yield 2
_: DeploymentHandle[MyDeployment] = None # type: ignore[assignment]
# # Streaming handle with generator method should give DeploymentResponseGenerator
# streaming_handle = handle.options(stream=True)
# gen_str = streaming_handle.stream_strings.remote()
# assert_type(gen_str, DeploymentResponseGenerator[str])
# # Iteration should yield str
# for item in gen_str:
# assert_type(item, str)
# break
# gen_int = streaming_handle.stream_ints.remote()
# assert_type(gen_int, DeploymentResponseGenerator[int])
# # Iteration should yield int
# for item in gen_int:
# assert_type(item, int)
# break
async def test_plugin_async_generator_iteration() -> None:
"""[REQUIRES PLUGIN] Test async iteration with inferred yield type."""
from typing import Generator
class MyDeployment:
def stream_bytes(self) -> Generator[bytes, None, None]:
yield b"chunk"
_: DeploymentHandle[MyDeployment] = None # type: ignore[assignment]
# streaming_handle = handle.options(stream=True)
# gen = streaming_handle.stream_bytes.remote()
# assert_type(gen, DeploymentResponseGenerator[bytes])
# # Async iteration should yield bytes
# async for chunk in gen:
# assert_type(chunk, bytes)
# break
def test_plugin_complex_return_types() -> None:
from typing import Dict, List, Optional, Tuple
class User:
name: str
age: int
class MyDeployment:
def get_users(self) -> List[User]:
return []
def get_user_dict(self) -> Dict[str, User]:
return {}
def get_optional(self) -> Optional[User]:
return None
def get_tuple(self) -> Tuple[str, int, User]:
return ("", 0, User())
_: DeploymentHandle[MyDeployment] = None # type: ignore[assignment]
# response_list = handle.get_users.remote()
# assert_type(response_list, DeploymentResponse[List[User]])
# users = response_list.result()
# assert_type(users, List[User])
# response_dict = handle.get_user_dict.remote()
# assert_type(response_dict, DeploymentResponse[Dict[str, User]])
# response_optional = handle.get_optional.remote()
# assert_type(response_optional, DeploymentResponse[Optional[User]])
# response_tuple = handle.get_tuple.remote()
# assert_type(response_tuple, DeploymentResponse[Tuple[str, int, User]])