Files
AI/참고/instructor-main/tests/test_list_response.py

65 lines
2.0 KiB
Python
Raw Normal View History

2026-05-12 19:40:31 +09:00
from __future__ import annotations
from collections.abc import Iterable as ABCIterable
from typing import Any
from pydantic import BaseModel
from instructor.dsl import ListResponse
from instructor.dsl.iterable import IterableBase
from instructor.mode import Mode
from instructor.processing.response import process_response
from instructor.utils.core import prepare_response_model
class User(BaseModel):
name: str
def test_listresponse_preserves_raw_response_on_slice() -> None:
raw: Any = {"provider": "test"}
resp = ListResponse([User(name="a"), User(name="b")], _raw_response=raw)
assert resp.get_raw_response() is raw
assert resp[0].name == "a"
sliced = resp[1:]
assert isinstance(sliced, ListResponse)
assert sliced.get_raw_response() is raw
assert sliced[0].name == "b"
def test_process_response_wraps_iterablebase_tasks_with_raw_response() -> None:
class FakeIterableResponse(BaseModel, IterableBase):
tasks: list[User]
@classmethod
def from_response( # type: ignore[override]
cls, _response: Any, **_kwargs: Any
) -> FakeIterableResponse:
return cls(tasks=[User(name="x"), User(name="y")])
# `process_response()` is typed with a BaseModel-bounded type variable for `response`,
# so use a BaseModel instance here to keep `ty` happy.
raw_response: Any = User(name="raw")
out = process_response(
raw_response,
response_model=FakeIterableResponse,
stream=False,
mode=Mode.TOOLS,
)
assert isinstance(out, ListResponse)
assert [u.name for u in out] == ["x", "y"]
assert out.get_raw_response() is raw_response
def test_prepare_response_model_supports_list_and_iterable() -> None:
prepared_list = prepare_response_model(list[User])
assert prepared_list is not None
assert issubclass(prepared_list, IterableBase)
prepared_iterable = prepare_response_model(ABCIterable[User]) # type: ignore[index]
assert prepared_iterable is not None
assert issubclass(prepared_iterable, IterableBase)