|
5 | 5 | import pathlib |
6 | 6 | from typing import Any, Mapping, TypeVar, cast |
7 | 7 | from datetime import date, datetime |
8 | | -from typing_extensions import Literal, get_args, override, get_type_hints |
| 8 | +from typing_extensions import Literal, get_args, override, get_type_hints as _get_type_hints |
9 | 9 |
|
10 | 10 | import anyio |
11 | 11 | import pydantic |
12 | 12 |
|
13 | 13 | from ._utils import ( |
14 | 14 | is_list, |
| 15 | + is_given, |
| 16 | + lru_cache, |
15 | 17 | is_mapping, |
16 | 18 | is_iterable, |
17 | 19 | ) |
@@ -108,6 +110,7 @@ class Params(TypedDict, total=False): |
108 | 110 | return cast(_T, transformed) |
109 | 111 |
|
110 | 112 |
|
| 113 | +@lru_cache(maxsize=8096) |
111 | 114 | def _get_annotated_type(type_: type) -> type | None: |
112 | 115 | """If the given type is an `Annotated` type then it is returned, if not `None` is returned. |
113 | 116 |
|
@@ -258,6 +261,11 @@ def _transform_typeddict( |
258 | 261 | result: dict[str, object] = {} |
259 | 262 | annotations = get_type_hints(expected_type, include_extras=True) |
260 | 263 | for key, value in data.items(): |
| 264 | + if not is_given(value): |
| 265 | + # we don't need to include `NotGiven` values here as they'll |
| 266 | + # be stripped out before the request is sent anyway |
| 267 | + continue |
| 268 | + |
261 | 269 | type_ = annotations.get(key) |
262 | 270 | if type_ is None: |
263 | 271 | # we do not have a type annotation for this field, leave it as is |
@@ -415,10 +423,25 @@ async def _async_transform_typeddict( |
415 | 423 | result: dict[str, object] = {} |
416 | 424 | annotations = get_type_hints(expected_type, include_extras=True) |
417 | 425 | for key, value in data.items(): |
| 426 | + if not is_given(value): |
| 427 | + # we don't need to include `NotGiven` values here as they'll |
| 428 | + # be stripped out before the request is sent anyway |
| 429 | + continue |
| 430 | + |
418 | 431 | type_ = annotations.get(key) |
419 | 432 | if type_ is None: |
420 | 433 | # we do not have a type annotation for this field, leave it as is |
421 | 434 | result[key] = value |
422 | 435 | else: |
423 | 436 | result[_maybe_transform_key(key, type_)] = await _async_transform_recursive(value, annotation=type_) |
424 | 437 | return result |
| 438 | + |
| 439 | + |
| 440 | +@lru_cache(maxsize=8096) |
| 441 | +def get_type_hints( |
| 442 | + obj: Any, |
| 443 | + globalns: dict[str, Any] | None = None, |
| 444 | + localns: Mapping[str, Any] | None = None, |
| 445 | + include_extras: bool = False, |
| 446 | +) -> dict[str, Any]: |
| 447 | + return _get_type_hints(obj, globalns=globalns, localns=localns, include_extras=include_extras) |
0 commit comments