Skip to content

Commit 2c4638b

Browse files
refactor(event_handler): use standard collections for types + refactor code (#6495)
* Using generics types + removing old code + fixing stuff * Using generics types + removing old code + fixing stuff * Using generics types + enabling ruff
1 parent 2a4e1ec commit 2c4638b

36 files changed

+139
-71
lines changed

aws_lambda_powertools/event_handler/api_gateway.py

+8-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from functools import partial
1313
from http import HTTPStatus
1414
from pathlib import Path
15-
from typing import TYPE_CHECKING, Any, Callable, Generic, Literal, Mapping, Match, Pattern, Sequence, TypeVar, cast
15+
from typing import TYPE_CHECKING, Any, Generic, Literal, Match, Pattern, TypeVar, cast
1616

1717
from typing_extensions import override
1818

@@ -59,6 +59,9 @@
5959
)
6060
from aws_lambda_powertools.utilities.data_classes.common import BaseProxyEvent
6161

62+
if TYPE_CHECKING:
63+
from collections.abc import Callable, Mapping, Sequence
64+
6265
logger = logging.getLogger(__name__)
6366

6467
_DYNAMIC_ROUTE_PATTERN = r"(<\w+>)"
@@ -68,6 +71,7 @@
6871
_NAMED_GROUP_BOUNDARY_PATTERN = rf"(?P\1[{_SAFE_URI}{_UNSAFE_URI}\\w]+)"
6972
_DEFAULT_OPENAPI_RESPONSE_DESCRIPTION = "Successful Response"
7073
_ROUTE_REGEX = "^{}$"
74+
_JSON_DUMP_CALL = partial(json.dumps, separators=(",", ":"), cls=Encoder)
7175

7276
ResponseEventT = TypeVar("ResponseEventT", bound=BaseProxyEvent)
7377
ResponseT = TypeVar("ResponseT")
@@ -830,7 +834,7 @@ class ResponseBuilder(Generic[ResponseEventT]):
830834
def __init__(
831835
self,
832836
response: Response,
833-
serializer: Callable[[Any], str] = partial(json.dumps, separators=(",", ":"), cls=Encoder),
837+
serializer: Callable[[Any], str] = _JSON_DUMP_CALL,
834838
route: Route | None = None,
835839
):
836840
self.response = response
@@ -1723,8 +1727,9 @@ def get_openapi_schema(
17231727
security = security or self.openapi_config.security
17241728
openapi_extensions = openapi_extensions or self.openapi_config.openapi_extensions
17251729

1730+
from pydantic.json_schema import GenerateJsonSchema
1731+
17261732
from aws_lambda_powertools.event_handler.openapi.compat import (
1727-
GenerateJsonSchema,
17281733
get_compat_model_name_map,
17291734
get_definitions,
17301735
)

aws_lambda_powertools/event_handler/appsync.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
import asyncio
44
import logging
55
import warnings
6-
from typing import TYPE_CHECKING, Any, Callable
6+
from typing import TYPE_CHECKING, Any
77

88
from aws_lambda_powertools.event_handler.graphql_appsync.exceptions import InvalidBatchResponse, ResolverNotFoundError
99
from aws_lambda_powertools.event_handler.graphql_appsync.router import Router
1010
from aws_lambda_powertools.utilities.data_classes import AppSyncResolverEvent
1111

1212
if TYPE_CHECKING:
13+
from collections.abc import Callable
14+
1315
from aws_lambda_powertools.utilities.typing import LambdaContext
1416

1517
from aws_lambda_powertools.warnings import PowertoolsUserWarning

aws_lambda_powertools/event_handler/bedrock_agent.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from __future__ import annotations
22

33
import json
4-
from typing import TYPE_CHECKING, Any, Callable
4+
from typing import TYPE_CHECKING, Any
55

66
from typing_extensions import override
77

@@ -14,6 +14,7 @@
1414
from aws_lambda_powertools.event_handler.openapi.constants import DEFAULT_API_VERSION, DEFAULT_OPENAPI_VERSION
1515

1616
if TYPE_CHECKING:
17+
from collections.abc import Callable
1718
from http import HTTPStatus
1819
from re import Match
1920

aws_lambda_powertools/event_handler/graphql_appsync/_registry.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
from __future__ import annotations
22

33
import logging
4-
from typing import Any, Callable
4+
from typing import TYPE_CHECKING, Any
5+
6+
if TYPE_CHECKING:
7+
from collections.abc import Callable
58

69
logger = logging.getLogger(__name__)
710

aws_lambda_powertools/event_handler/graphql_appsync/base.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
from __future__ import annotations
22

33
from abc import ABC, abstractmethod
4-
from typing import Callable
4+
from typing import TYPE_CHECKING
5+
6+
if TYPE_CHECKING:
7+
from collections.abc import Callable
58

69

710
class BaseRouter(ABC):

aws_lambda_powertools/event_handler/graphql_appsync/router.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
from __future__ import annotations
22

3-
from typing import TYPE_CHECKING, Callable
3+
from typing import TYPE_CHECKING
44

55
from aws_lambda_powertools.event_handler.graphql_appsync._registry import ResolverRegistry
66
from aws_lambda_powertools.event_handler.graphql_appsync.base import BaseRouter
77

88
if TYPE_CHECKING:
9+
from collections.abc import Callable
10+
911
from aws_lambda_powertools.utilities.data_classes.appsync_resolver_event import AppSyncResolverEvent
1012
from aws_lambda_powertools.utilities.typing.lambda_context import LambdaContext
1113

aws_lambda_powertools/event_handler/lambda_function_url.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
from __future__ import annotations
22

3-
from typing import TYPE_CHECKING, Callable, Pattern
3+
from typing import TYPE_CHECKING, Pattern
44

55
from aws_lambda_powertools.event_handler.api_gateway import (
66
ApiGatewayResolver,
77
ProxyEventType,
88
)
99

1010
if TYPE_CHECKING:
11+
from collections.abc import Callable
1112
from http import HTTPStatus
1213

1314
from aws_lambda_powertools.event_handler import CORSConfig

aws_lambda_powertools/event_handler/middlewares/openapi_validation.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ def _validate_field(
365365
"""
366366
Validate a field, and append any errors to the existing_errors list.
367367
"""
368-
validated_value, errors = field.validate(value, value, loc=loc)
368+
validated_value, errors = field.validate(value=value, loc=loc)
369369

370370
if isinstance(errors, list):
371371
processed_errors = _regenerate_error_with_loc(errors=errors, loc_prefix=())

aws_lambda_powertools/event_handler/openapi/compat.py

+16-18
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,30 @@
11
# mypy: ignore-errors
2-
# flake8: noqa
32
from __future__ import annotations
43

54
from collections import deque
6-
from copy import copy
5+
from collections.abc import Mapping, Sequence
76

87
# MAINTENANCE: remove when deprecating Pydantic v1. Mypy doesn't handle two different code paths that import different
98
# versions of a module, so we need to ignore errors here.
10-
119
from dataclasses import dataclass, is_dataclass
12-
from enum import Enum
13-
from typing import TYPE_CHECKING, Any, Deque, FrozenSet, List, Mapping, Sequence, Set, Tuple, Union
14-
15-
from typing_extensions import Annotated, Literal, get_origin, get_args
16-
17-
from pydantic import BaseModel, create_model
18-
from pydantic.fields import FieldInfo
10+
from typing import TYPE_CHECKING, Any, Deque, FrozenSet, List, Set, Tuple, Union
1911

20-
from aws_lambda_powertools.event_handler.openapi.types import COMPONENT_REF_PREFIX, UnionType
21-
22-
from pydantic import TypeAdapter, ValidationError
12+
from pydantic import BaseModel, TypeAdapter, ValidationError, create_model
2313

2414
# Importing from internal libraries in Pydantic may introduce potential risks, as these internal libraries
2515
# are not part of the public API and may change without notice in future releases.
2616
# We use this for forward reference, as it allows us to handle forward references in type annotations.
2717
from pydantic._internal._typing_extra import eval_type_lenient
28-
from pydantic.fields import FieldInfo
2918
from pydantic._internal._utils import lenient_issubclass
30-
from pydantic.json_schema import GenerateJsonSchema, JsonSchemaValue
3119
from pydantic_core import PydanticUndefined, PydanticUndefinedType
20+
from typing_extensions import Annotated, Literal, get_args, get_origin
21+
22+
from aws_lambda_powertools.event_handler.openapi.types import UnionType
3223

3324
if TYPE_CHECKING:
25+
from pydantic.fields import FieldInfo
26+
from pydantic.json_schema import GenerateJsonSchema, JsonSchemaValue
27+
3428
from aws_lambda_powertools.event_handler.openapi.types import IncEx, ModelNameMap
3529

3630
Undefined = PydanticUndefined
@@ -119,7 +113,10 @@ def serialize(
119113
)
120114

121115
def validate(
122-
self, value: Any, values: dict[str, Any] = {}, *, loc: tuple[int | str, ...] = ()
116+
self,
117+
value: Any,
118+
*,
119+
loc: tuple[int | str, ...] = (),
123120
) -> tuple[Any, list[dict[str, Any]] | None]:
124121
try:
125122
return (self._type_adapter.validate_python(value, from_attributes=True), None)
@@ -184,7 +181,8 @@ def copy_field_info(*, field_info: FieldInfo, annotation: Any) -> FieldInfo:
184181

185182
def get_missing_field_error(loc: tuple[str, ...]) -> dict[str, Any]:
186183
error = ValidationError.from_exception_data(
187-
"Field required", [{"type": "missing", "loc": loc, "input": {}}]
184+
"Field required",
185+
[{"type": "missing", "loc": loc, "input": {}}],
188186
).errors()[0]
189187
error["input"] = None
190188
return error
@@ -308,7 +306,7 @@ def value_is_sequence(value: Any) -> bool:
308306

309307
def _annotation_is_complex(annotation: type[Any] | None) -> bool:
310308
return (
311-
lenient_issubclass(annotation, (BaseModel, Mapping)) # TODO: UploadFile
309+
lenient_issubclass(annotation, (BaseModel, Mapping)) # Keep it to UploadFile
312310
or _annotation_is_sequence(annotation)
313311
or is_dataclass(annotation)
314312
)

aws_lambda_powertools/event_handler/openapi/dependant.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import inspect
44
import re
5-
from typing import TYPE_CHECKING, Any, Callable, ForwardRef, cast
5+
from typing import TYPE_CHECKING, Any, ForwardRef, cast
66

77
from aws_lambda_powertools.event_handler.openapi.compat import (
88
ModelField,
@@ -27,6 +27,8 @@
2727
from aws_lambda_powertools.event_handler.openapi.types import OpenAPIResponse, OpenAPIResponseContentModel
2828

2929
if TYPE_CHECKING:
30+
from collections.abc import Callable
31+
3032
from pydantic import BaseModel
3133

3234
"""

aws_lambda_powertools/event_handler/openapi/encoders.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
from pathlib import Path, PurePath
99
from re import Pattern
1010
from types import GeneratorType
11-
from typing import TYPE_CHECKING, Any, Callable
11+
from typing import TYPE_CHECKING, Any
1212
from uuid import UUID
1313

1414
from pydantic import BaseModel
@@ -17,6 +17,8 @@
1717
from aws_lambda_powertools.event_handler.openapi.compat import _model_dump
1818

1919
if TYPE_CHECKING:
20+
from collections.abc import Callable
21+
2022
from aws_lambda_powertools.event_handler.openapi.types import IncEx
2123

2224
from aws_lambda_powertools.event_handler.openapi.exceptions import SerializationError

aws_lambda_powertools/event_handler/openapi/exceptions.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
from typing import Any, Literal, Sequence
1+
from collections.abc import Sequence
2+
from typing import Any, Literal
23

34

45
class ValidationException(Exception):

aws_lambda_powertools/event_handler/openapi/params.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import inspect
44
from enum import Enum
5-
from typing import TYPE_CHECKING, Any, Callable, Literal
5+
from typing import TYPE_CHECKING, Any, Literal
66

77
from pydantic import BaseConfig
88
from pydantic.fields import FieldInfo
@@ -20,6 +20,8 @@
2020
)
2121

2222
if TYPE_CHECKING:
23+
from collections.abc import Callable
24+
2325
from aws_lambda_powertools.event_handler.openapi.models import Example
2426
from aws_lambda_powertools.event_handler.openapi.types import CacheKey
2527

aws_lambda_powertools/event_handler/openapi/types.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
from __future__ import annotations
22

33
import types
4-
from typing import TYPE_CHECKING, Any, Callable, Dict, Set, Type, TypedDict, Union
4+
from typing import TYPE_CHECKING, Any, Dict, Set, Type, TypedDict, Union
55

66
if TYPE_CHECKING:
7+
from collections.abc import Callable
78
from enum import Enum
89

910
from pydantic import BaseModel

aws_lambda_powertools/event_handler/util.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
from __future__ import annotations
22

3-
from typing import Any, Dict, List, Mapping
3+
from typing import TYPE_CHECKING, Any
4+
5+
if TYPE_CHECKING:
6+
from collections.abc import Mapping
47

58

69
class _FrozenDict(dict):
@@ -18,7 +21,7 @@ def __hash__(self):
1821
return hash(frozenset(self.keys()))
1922

2023

21-
class _FrozenListDict(List[Dict[str, List[str]]]):
24+
class _FrozenListDict(list[dict[str, list[str]]]):
2225
"""
2326
Freezes a list of dictionaries containing lists of strings.
2427

aws_lambda_powertools/event_handler/vpc_lattice.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
from __future__ import annotations
22

3-
from typing import TYPE_CHECKING, Callable, Pattern
3+
from typing import TYPE_CHECKING, Pattern
44

55
from aws_lambda_powertools.event_handler.api_gateway import (
66
ApiGatewayResolver,
77
ProxyEventType,
88
)
99

1010
if TYPE_CHECKING:
11+
from collections.abc import Callable
1112
from http import HTTPStatus
1213

1314
from aws_lambda_powertools.event_handler import CORSConfig

tests/functional/event_handler/_pydantic/conftest.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import json
24

35
import fastjsonschema

tests/functional/event_handler/_pydantic/test_api_gateway.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
from pydantic import BaseModel
24

35
from aws_lambda_powertools.event_handler import content_types

tests/functional/event_handler/_pydantic/test_openapi_config.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import json
24

35
from aws_lambda_powertools.event_handler import APIGatewayRestResolver

tests/functional/event_handler/_pydantic/test_openapi_encoders.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import math
24
from collections import deque
35
from dataclasses import dataclass

tests/functional/event_handler/_pydantic/test_openapi_extensions.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import json
24

35
from aws_lambda_powertools.event_handler.api_gateway import APIGatewayRestResolver, Router

tests/functional/event_handler/_pydantic/test_openapi_params.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ class User(BaseModel):
278278

279279
@app.get("/")
280280
def handler() -> User:
281-
return User(name="Ruben Fonseca")
281+
return User(name="Powertools")
282282

283283
schema = app.get_openapi_schema()
284284
assert len(schema.paths.keys()) == 1

tests/functional/event_handler/_pydantic/test_openapi_security.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import pytest
24

35
from aws_lambda_powertools.event_handler import APIGatewayRestResolver

tests/functional/event_handler/_pydantic/test_openapi_security_schemes.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
24
from aws_lambda_powertools.event_handler.openapi.models import (
35
APIKey,

tests/functional/event_handler/_pydantic/test_openapi_servers.py

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
from aws_lambda_powertools.event_handler.api_gateway import APIGatewayRestResolver
24
from aws_lambda_powertools.event_handler.openapi.models import Server
35

0 commit comments

Comments
 (0)