Skip to content

Commit f070165

Browse files
chore(internal): loosen type var restrictions (#248)
1 parent acd29fd commit f070165

17 files changed

+71
-146
lines changed

src/finch/_base_client.py

+19-22
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@
4848
Body,
4949
Omit,
5050
Query,
51-
ModelT,
5251
Headers,
5352
Timeout,
5453
NotGiven,
@@ -61,7 +60,6 @@
6160
HttpxSendArgs,
6261
AsyncTransport,
6362
RequestOptions,
64-
UnknownResponse,
6563
ModelBuilderProtocol,
6664
BinaryResponseContent,
6765
)
@@ -142,7 +140,7 @@ def __init__(
142140
self.params = params
143141

144142

145-
class BasePage(GenericModel, Generic[ModelT]):
143+
class BasePage(GenericModel, Generic[_T]):
146144
"""
147145
Defines the core interface for pagination.
148146
@@ -155,7 +153,7 @@ class BasePage(GenericModel, Generic[ModelT]):
155153
"""
156154

157155
_options: FinalRequestOptions = PrivateAttr()
158-
_model: Type[ModelT] = PrivateAttr()
156+
_model: Type[_T] = PrivateAttr()
159157

160158
def has_next_page(self) -> bool:
161159
items = self._get_page_items()
@@ -166,7 +164,7 @@ def has_next_page(self) -> bool:
166164
def next_page_info(self) -> Optional[PageInfo]:
167165
...
168166

169-
def _get_page_items(self) -> Iterable[ModelT]: # type: ignore[empty-body]
167+
def _get_page_items(self) -> Iterable[_T]: # type: ignore[empty-body]
170168
...
171169

172170
def _params_from_url(self, url: URL) -> httpx.QueryParams:
@@ -191,13 +189,13 @@ def _info_to_options(self, info: PageInfo) -> FinalRequestOptions:
191189
raise ValueError("Unexpected PageInfo state")
192190

193191

194-
class BaseSyncPage(BasePage[ModelT], Generic[ModelT]):
192+
class BaseSyncPage(BasePage[_T], Generic[_T]):
195193
_client: SyncAPIClient = pydantic.PrivateAttr()
196194

197195
def _set_private_attributes(
198196
self,
199197
client: SyncAPIClient,
200-
model: Type[ModelT],
198+
model: Type[_T],
201199
options: FinalRequestOptions,
202200
) -> None:
203201
self._model = model
@@ -212,7 +210,7 @@ def _set_private_attributes(
212210
# methods should continue to work as expected as there is an alternative method
213211
# to cast a model to a dictionary, model.dict(), which is used internally
214212
# by pydantic.
215-
def __iter__(self) -> Iterator[ModelT]: # type: ignore
213+
def __iter__(self) -> Iterator[_T]: # type: ignore
216214
for page in self.iter_pages():
217215
for item in page._get_page_items():
218216
yield item
@@ -237,13 +235,13 @@ def get_next_page(self: SyncPageT) -> SyncPageT:
237235
return self._client._request_api_list(self._model, page=self.__class__, options=options)
238236

239237

240-
class AsyncPaginator(Generic[ModelT, AsyncPageT]):
238+
class AsyncPaginator(Generic[_T, AsyncPageT]):
241239
def __init__(
242240
self,
243241
client: AsyncAPIClient,
244242
options: FinalRequestOptions,
245243
page_cls: Type[AsyncPageT],
246-
model: Type[ModelT],
244+
model: Type[_T],
247245
) -> None:
248246
self._model = model
249247
self._client = client
@@ -266,7 +264,7 @@ def _parser(resp: AsyncPageT) -> AsyncPageT:
266264

267265
return await self._client.request(self._page_cls, self._options)
268266

269-
async def __aiter__(self) -> AsyncIterator[ModelT]:
267+
async def __aiter__(self) -> AsyncIterator[_T]:
270268
# https://github.com/microsoft/pyright/issues/3464
271269
page = cast(
272270
AsyncPageT,
@@ -276,20 +274,20 @@ async def __aiter__(self) -> AsyncIterator[ModelT]:
276274
yield item
277275

278276

279-
class BaseAsyncPage(BasePage[ModelT], Generic[ModelT]):
277+
class BaseAsyncPage(BasePage[_T], Generic[_T]):
280278
_client: AsyncAPIClient = pydantic.PrivateAttr()
281279

282280
def _set_private_attributes(
283281
self,
284-
model: Type[ModelT],
282+
model: Type[_T],
285283
client: AsyncAPIClient,
286284
options: FinalRequestOptions,
287285
) -> None:
288286
self._model = model
289287
self._client = client
290288
self._options = options
291289

292-
async def __aiter__(self) -> AsyncIterator[ModelT]:
290+
async def __aiter__(self) -> AsyncIterator[_T]:
293291
async for page in self.iter_pages():
294292
for item in page._get_page_items():
295293
yield item
@@ -528,7 +526,7 @@ def _process_response_data(
528526
if data is None:
529527
return cast(ResponseT, None)
530528

531-
if cast_to is UnknownResponse:
529+
if cast_to is object:
532530
return cast(ResponseT, data)
533531

534532
try:
@@ -970,7 +968,7 @@ def _retry_request(
970968

971969
def _request_api_list(
972970
self,
973-
model: Type[ModelT],
971+
model: Type[object],
974972
page: Type[SyncPageT],
975973
options: FinalRequestOptions,
976974
) -> SyncPageT:
@@ -1132,7 +1130,7 @@ def get_api_list(
11321130
self,
11331131
path: str,
11341132
*,
1135-
model: Type[ModelT],
1133+
model: Type[object],
11361134
page: Type[SyncPageT],
11371135
body: Body | None = None,
11381136
options: RequestOptions = {},
@@ -1434,10 +1432,10 @@ async def _retry_request(
14341432

14351433
def _request_api_list(
14361434
self,
1437-
model: Type[ModelT],
1435+
model: Type[_T],
14381436
page: Type[AsyncPageT],
14391437
options: FinalRequestOptions,
1440-
) -> AsyncPaginator[ModelT, AsyncPageT]:
1438+
) -> AsyncPaginator[_T, AsyncPageT]:
14411439
return AsyncPaginator(client=self, options=options, page_cls=page, model=model)
14421440

14431441
@overload
@@ -1584,13 +1582,12 @@ def get_api_list(
15841582
self,
15851583
path: str,
15861584
*,
1587-
# TODO: support paginating `str`
1588-
model: Type[ModelT],
1585+
model: Type[_T],
15891586
page: Type[AsyncPageT],
15901587
body: Body | None = None,
15911588
options: RequestOptions = {},
15921589
method: str = "get",
1593-
) -> AsyncPaginator[ModelT, AsyncPageT]:
1590+
) -> AsyncPaginator[_T, AsyncPageT]:
15941591
opts = FinalRequestOptions.construct(method=method, url=path, json_data=body, **options)
15951592
return self._request_api_list(model, page, opts)
15961593

src/finch/_response.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
import httpx
1111

12-
from ._types import NoneType, UnknownResponse, BinaryResponseContent
12+
from ._types import NoneType, BinaryResponseContent
1313
from ._utils import is_given, extract_type_var_from_base
1414
from ._models import BaseModel, is_basemodel
1515
from ._constants import RAW_RESPONSE_HEADER
@@ -162,7 +162,7 @@ def _parse(self) -> R:
162162
# `ResponseT` TypeVar, however if that TypeVar is ever updated in the future, then
163163
# this function would become unsafe but a type checker would not report an error.
164164
if (
165-
cast_to is not UnknownResponse
165+
cast_to is not object
166166
and not origin is list
167167
and not origin is dict
168168
and not origin is Union

src/finch/_types.py

+11-6
Original file line numberDiff line numberDiff line change
@@ -258,11 +258,6 @@ class RequestOptions(TypedDict, total=False):
258258
idempotency_key: str
259259

260260

261-
# Sentinel class used when the response type is an object with an unknown schema
262-
class UnknownResponse:
263-
...
264-
265-
266261
# Sentinel class used until PEP 0661 is accepted
267262
class NotGiven:
268263
"""
@@ -339,7 +334,17 @@ def get(self, __key: str) -> str | None:
339334

340335
ResponseT = TypeVar(
341336
"ResponseT",
342-
bound="Union[str, None, BaseModel, List[Any], Dict[str, Any], Response, UnknownResponse, ModelBuilderProtocol, BinaryResponseContent]",
337+
bound=Union[
338+
object,
339+
str,
340+
None,
341+
"BaseModel",
342+
List[Any],
343+
Dict[str, Any],
344+
Response,
345+
ModelBuilderProtocol,
346+
BinaryResponseContent,
347+
],
343348
)
344349

345350
StrBytesIntFloat = Union[str, bytes, int, float]

src/finch/pagination.py

+26-25
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
from httpx import Response
77

8-
from ._types import ModelT
98
from ._utils import is_mapping
109
from ._models import BaseModel
1110
from ._base_client import BasePage, PageInfo, BaseSyncPage, BaseAsyncPage
@@ -24,12 +23,14 @@
2423

2524
_BaseModelT = TypeVar("_BaseModelT", bound=BaseModel)
2625

26+
_T = TypeVar("_T")
2727

28-
class SyncSinglePage(BaseSyncPage[ModelT], BasePage[ModelT], Generic[ModelT]):
29-
items: List[ModelT]
28+
29+
class SyncSinglePage(BaseSyncPage[_T], BasePage[_T], Generic[_T]):
30+
items: List[_T]
3031

3132
@override
32-
def _get_page_items(self) -> List[ModelT]:
33+
def _get_page_items(self) -> List[_T]:
3334
return self.items
3435

3536
@override
@@ -50,11 +51,11 @@ def build(cls: Type[_BaseModelT], *, response: Response, data: object) -> _BaseM
5051
)
5152

5253

53-
class AsyncSinglePage(BaseAsyncPage[ModelT], BasePage[ModelT], Generic[ModelT]):
54-
items: List[ModelT]
54+
class AsyncSinglePage(BaseAsyncPage[_T], BasePage[_T], Generic[_T]):
55+
items: List[_T]
5556

5657
@override
57-
def _get_page_items(self) -> List[ModelT]:
58+
def _get_page_items(self) -> List[_T]:
5859
return self.items
5960

6061
@override
@@ -75,11 +76,11 @@ def build(cls: Type[_BaseModelT], *, response: Response, data: object) -> _BaseM
7576
)
7677

7778

78-
class SyncResponsesPage(BaseSyncPage[ModelT], BasePage[ModelT], Generic[ModelT]):
79-
responses: List[ModelT]
79+
class SyncResponsesPage(BaseSyncPage[_T], BasePage[_T], Generic[_T]):
80+
responses: List[_T]
8081

8182
@override
82-
def _get_page_items(self) -> List[ModelT]:
83+
def _get_page_items(self) -> List[_T]:
8384
return self.responses
8485

8586
@override
@@ -91,11 +92,11 @@ def next_page_info(self) -> None:
9192
return None
9293

9394

94-
class AsyncResponsesPage(BaseAsyncPage[ModelT], BasePage[ModelT], Generic[ModelT]):
95-
responses: List[ModelT]
95+
class AsyncResponsesPage(BaseAsyncPage[_T], BasePage[_T], Generic[_T]):
96+
responses: List[_T]
9697

9798
@override
98-
def _get_page_items(self) -> List[ModelT]:
99+
def _get_page_items(self) -> List[_T]:
99100
return self.responses
100101

101102
@override
@@ -107,12 +108,12 @@ def next_page_info(self) -> None:
107108
return None
108109

109110

110-
class SyncIndividualsPage(BaseSyncPage[ModelT], BasePage[ModelT], Generic[ModelT]):
111-
individuals: List[ModelT]
111+
class SyncIndividualsPage(BaseSyncPage[_T], BasePage[_T], Generic[_T]):
112+
individuals: List[_T]
112113
paging: Paging
113114

114115
@override
115-
def _get_page_items(self) -> List[ModelT]:
116+
def _get_page_items(self) -> List[_T]:
116117
return self.individuals
117118

118119
@override
@@ -134,12 +135,12 @@ def next_page_info(self) -> Optional[PageInfo]:
134135
return None
135136

136137

137-
class AsyncIndividualsPage(BaseAsyncPage[ModelT], BasePage[ModelT], Generic[ModelT]):
138-
individuals: List[ModelT]
138+
class AsyncIndividualsPage(BaseAsyncPage[_T], BasePage[_T], Generic[_T]):
139+
individuals: List[_T]
139140
paging: Paging
140141

141142
@override
142-
def _get_page_items(self) -> List[ModelT]:
143+
def _get_page_items(self) -> List[_T]:
143144
return self.individuals
144145

145146
@override
@@ -161,12 +162,12 @@ def next_page_info(self) -> Optional[PageInfo]:
161162
return None
162163

163164

164-
class SyncPage(BaseSyncPage[ModelT], BasePage[ModelT], Generic[ModelT]):
165+
class SyncPage(BaseSyncPage[_T], BasePage[_T], Generic[_T]):
165166
paging: Paging
166-
data: List[ModelT]
167+
data: List[_T]
167168

168169
@override
169-
def _get_page_items(self) -> List[ModelT]:
170+
def _get_page_items(self) -> List[_T]:
170171
return self.data
171172

172173
@override
@@ -188,12 +189,12 @@ def next_page_info(self) -> Optional[PageInfo]:
188189
return None
189190

190191

191-
class AsyncPage(BaseAsyncPage[ModelT], BasePage[ModelT], Generic[ModelT]):
192+
class AsyncPage(BaseAsyncPage[_T], BasePage[_T], Generic[_T]):
192193
paging: Paging
193-
data: List[ModelT]
194+
data: List[_T]
194195

195196
@override
196-
def _get_page_items(self) -> List[ModelT]:
197+
def _get_page_items(self) -> List[_T]:
197198
return self.data
198199

199200
@override

src/finch/resources/account.py

+1-7
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,7 @@
55
import httpx
66

77
from ..types import Introspection, DisconnectResponse
8-
from .._types import (
9-
NOT_GIVEN,
10-
Body,
11-
Query,
12-
Headers,
13-
NotGiven,
14-
)
8+
from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven
159
from .._compat import cached_property
1610
from .._resource import SyncAPIResource, AsyncAPIResource
1711
from .._response import to_raw_response_wrapper, async_to_raw_response_wrapper

src/finch/resources/hris/benefits/benefits.py

+1-7
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,7 @@
66

77
import httpx
88

9-
from ...._types import (
10-
NOT_GIVEN,
11-
Body,
12-
Query,
13-
Headers,
14-
NotGiven,
15-
)
9+
from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven
1610
from ...._utils import maybe_transform
1711
from ...._compat import cached_property
1812
from .individuals import Individuals, AsyncIndividuals, IndividualsWithRawResponse, AsyncIndividualsWithRawResponse

0 commit comments

Comments
 (0)