Skip to content

Commit 9022bd3

Browse files
committed
refactor(shared): add from __future__ import annotations
and update code according to ruff rules TCH, UP006, UP007, UP037 and FA100.
1 parent 2d59b7a commit 9022bd3

File tree

4 files changed

+49
-40
lines changed

4 files changed

+49
-40
lines changed

aws_lambda_powertools/shared/cookies.py

+14-10
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
from datetime import datetime
1+
from __future__ import annotations
2+
23
from enum import Enum
34
from io import StringIO
4-
from typing import List, Optional
5+
from typing import TYPE_CHECKING
6+
7+
if TYPE_CHECKING:
8+
from datetime import datetime
59

610

711
class SameSite(Enum):
@@ -41,10 +45,10 @@ def __init__(
4145
domain: str = "",
4246
secure: bool = True,
4347
http_only: bool = False,
44-
max_age: Optional[int] = None,
45-
expires: Optional[datetime] = None,
46-
same_site: Optional[SameSite] = None,
47-
custom_attributes: Optional[List[str]] = None,
48+
max_age: int | None = None,
49+
expires: datetime | None = None,
50+
same_site: SameSite | None = None,
51+
custom_attributes: list[str] | None = None,
4852
):
4953
"""
5054
@@ -62,13 +66,13 @@ def __init__(
6266
Marks the cookie as secure, only sendable to the server with an encrypted request over the HTTPS protocol
6367
http_only: bool
6468
Enabling this attribute makes the cookie inaccessible to the JavaScript `Document.cookie` API
65-
max_age: Optional[int]
69+
max_age: int | None
6670
Defines the period of time after which the cookie is invalid. Use negative values to force cookie deletion.
67-
expires: Optional[datetime]
71+
expires: datetime | None
6872
Defines a date where the permanent cookie expires.
69-
same_site: Optional[SameSite]
73+
same_site: SameSite | None
7074
Determines if the cookie should be sent to third party websites
71-
custom_attributes: Optional[List[str]]
75+
custom_attributes: list[str] | None
7276
List of additional custom attributes to set on the cookie
7377
"""
7478
self.name = name

aws_lambda_powertools/shared/dynamodb_deserializer.py

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
from __future__ import annotations
2+
13
from decimal import Clamped, Context, Decimal, Inexact, Overflow, Rounded, Underflow
2-
from typing import Any, Callable, Dict, Optional, Sequence, Set
4+
from typing import Any, Callable, Sequence
35

46
# NOTE: DynamoDB supports up to 38 digits precision
57
# Therefore, this ensures our Decimal follows what's stored in the table
@@ -21,7 +23,7 @@ class TypeDeserializer:
2123
since we don't support Python 2.
2224
"""
2325

24-
def deserialize(self, value: Dict) -> Any:
26+
def deserialize(self, value: dict) -> Any:
2527
"""Deserialize DynamoDB data types into Python types.
2628
2729
Parameters
@@ -57,7 +59,7 @@ def deserialize(self, value: Dict) -> Any:
5759
"""
5860

5961
dynamodb_type = list(value.keys())[0]
60-
deserializer: Optional[Callable] = getattr(self, f"_deserialize_{dynamodb_type}".lower(), None)
62+
deserializer: Callable | None = getattr(self, f"_deserialize_{dynamodb_type}".lower(), None)
6163
if deserializer is None:
6264
raise TypeError(f"Dynamodb type {dynamodb_type} is not supported")
6365

@@ -78,17 +80,17 @@ def _deserialize_s(self, value: str) -> str:
7880
def _deserialize_b(self, value: bytes) -> bytes:
7981
return value
8082

81-
def _deserialize_ns(self, value: Sequence[str]) -> Set[Decimal]:
83+
def _deserialize_ns(self, value: Sequence[str]) -> set[Decimal]:
8284
return set(map(self._deserialize_n, value))
8385

84-
def _deserialize_ss(self, value: Sequence[str]) -> Set[str]:
86+
def _deserialize_ss(self, value: Sequence[str]) -> set[str]:
8587
return set(map(self._deserialize_s, value))
8688

87-
def _deserialize_bs(self, value: Sequence[bytes]) -> Set[bytes]:
89+
def _deserialize_bs(self, value: Sequence[bytes]) -> set[bytes]:
8890
return set(map(self._deserialize_b, value))
8991

90-
def _deserialize_l(self, value: Sequence[Dict]) -> Sequence[Any]:
92+
def _deserialize_l(self, value: Sequence[dict]) -> Sequence[Any]:
9193
return [self.deserialize(v) for v in value]
9294

93-
def _deserialize_m(self, value: Dict) -> Dict:
95+
def _deserialize_m(self, value: dict) -> dict:
9496
return {k: self.deserialize(v) for k, v in value.items()}

aws_lambda_powertools/shared/functions.py

+11-11
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import warnings
99
from binascii import Error as BinAsciiError
1010
from pathlib import Path
11-
from typing import Any, Dict, Generator, Optional, Union, overload
11+
from typing import Any, Generator, overload
1212

1313
from aws_lambda_powertools.shared import constants
1414

@@ -32,7 +32,7 @@ def strtobool(value: str) -> bool:
3232
raise ValueError(f"invalid truth value {value!r}")
3333

3434

35-
def resolve_truthy_env_var_choice(env: str, choice: Optional[bool] = None) -> bool:
35+
def resolve_truthy_env_var_choice(env: str, choice: bool | None = None) -> bool:
3636
"""Pick explicit choice over truthy env value, if available, otherwise return truthy env value
3737
3838
NOTE: Environment variable should be resolved by the caller.
@@ -52,27 +52,27 @@ def resolve_truthy_env_var_choice(env: str, choice: Optional[bool] = None) -> bo
5252
return choice if choice is not None else strtobool(env)
5353

5454

55-
def resolve_max_age(env: str, choice: Optional[int]) -> int:
55+
def resolve_max_age(env: str, choice: int | None) -> int:
5656
"""Resolve max age value"""
5757
return choice if choice is not None else int(env)
5858

5959

6060
@overload
61-
def resolve_env_var_choice(env: Optional[str], choice: float) -> float: ...
61+
def resolve_env_var_choice(env: str | None, choice: float) -> float: ...
6262

6363

6464
@overload
65-
def resolve_env_var_choice(env: Optional[str], choice: str) -> str: ...
65+
def resolve_env_var_choice(env: str | None, choice: str) -> str: ...
6666

6767

6868
@overload
69-
def resolve_env_var_choice(env: Optional[str], choice: Optional[str]) -> str: ...
69+
def resolve_env_var_choice(env: str | None, choice: str | None) -> str: ...
7070

7171

7272
def resolve_env_var_choice(
73-
env: Optional[str] = None,
74-
choice: Optional[Union[str, float]] = None,
75-
) -> Optional[Union[str, float]]:
73+
env: str | None = None,
74+
choice: str | float | None = None,
75+
) -> str | float | None:
7676
"""Pick explicit choice over env, if available, otherwise return env value received
7777
7878
NOTE: Environment variable should be resolved by the caller.
@@ -136,12 +136,12 @@ def powertools_debug_is_set() -> bool:
136136
return False
137137

138138

139-
def slice_dictionary(data: Dict, chunk_size: int) -> Generator[Dict, None, None]:
139+
def slice_dictionary(data: dict, chunk_size: int) -> Generator[dict, None, None]:
140140
for _ in range(0, len(data), chunk_size):
141141
yield {dict_key: data[dict_key] for dict_key in itertools.islice(data, chunk_size)}
142142

143143

144-
def extract_event_from_common_models(data: Any) -> Dict | Any:
144+
def extract_event_from_common_models(data: Any) -> dict | Any:
145145
"""Extract raw event from common types used in Powertools
146146
147147
If event cannot be extracted, return received data as is.

aws_lambda_powertools/shared/headers_serializer.py

+14-11
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
from __future__ import annotations
2+
13
import warnings
24
from collections import defaultdict
3-
from typing import Any, Dict, List, Union
5+
from typing import TYPE_CHECKING, Any
46

5-
from aws_lambda_powertools.shared.cookies import Cookie
7+
if TYPE_CHECKING:
8+
from aws_lambda_powertools.shared.cookies import Cookie
69

710

811
class BaseHeadersSerializer:
@@ -11,23 +14,23 @@ class BaseHeadersSerializer:
1114
ALB and Lambda Function URL response payload.
1215
"""
1316

14-
def serialize(self, headers: Dict[str, Union[str, List[str]]], cookies: List[Cookie]) -> Dict[str, Any]:
17+
def serialize(self, headers: dict[str, str | list[str]], cookies: list[Cookie]) -> dict[str, Any]:
1518
"""
1619
Serializes headers and cookies according to the request type.
1720
Returns a dict that can be merged with the response payload.
1821
1922
Parameters
2023
----------
21-
headers: Dict[str, List[str]]
24+
headers: dict[str, str | list[str]]
2225
A dictionary of headers to set in the response
23-
cookies: List[str]
26+
cookies: list[Cookie]
2427
A list of cookies to set in the response
2528
"""
2629
raise NotImplementedError()
2730

2831

2932
class HttpApiHeadersSerializer(BaseHeadersSerializer):
30-
def serialize(self, headers: Dict[str, Union[str, List[str]]], cookies: List[Cookie]) -> Dict[str, Any]:
33+
def serialize(self, headers: dict[str, str | list[str]], cookies: list[Cookie]) -> dict[str, Any]:
3134
"""
3235
When using HTTP APIs or LambdaFunctionURLs, everything is taken care automatically for us.
3336
We can directly assign a list of cookies and a dict of headers to the response payload, and the
@@ -39,7 +42,7 @@ def serialize(self, headers: Dict[str, Union[str, List[str]]], cookies: List[Coo
3942

4043
# Format 2.0 doesn't have multiValueHeaders or multiValueQueryStringParameters fields.
4144
# Duplicate headers are combined with commas and included in the headers field.
42-
combined_headers: Dict[str, str] = {}
45+
combined_headers: dict[str, str] = {}
4346
for key, values in headers.items():
4447
# omit headers with explicit null values
4548
if values is None:
@@ -54,7 +57,7 @@ def serialize(self, headers: Dict[str, Union[str, List[str]]], cookies: List[Coo
5457

5558

5659
class MultiValueHeadersSerializer(BaseHeadersSerializer):
57-
def serialize(self, headers: Dict[str, Union[str, List[str]]], cookies: List[Cookie]) -> Dict[str, Any]:
60+
def serialize(self, headers: dict[str, str | list[str]], cookies: list[Cookie]) -> dict[str, Any]:
5861
"""
5962
When using REST APIs, headers can be encoded using the `multiValueHeaders` key on the response.
6063
This is also the case when using an ALB integration with the `multiValueHeaders` option enabled.
@@ -63,7 +66,7 @@ def serialize(self, headers: Dict[str, Union[str, List[str]]], cookies: List[Coo
6366
https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html#api-gateway-simple-proxy-for-lambda-output-format
6467
https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html#multi-value-headers-response
6568
"""
66-
payload: Dict[str, List[str]] = defaultdict(list)
69+
payload: dict[str, list[str]] = defaultdict(list)
6770
for key, values in headers.items():
6871
# omit headers with explicit null values
6972
if values is None:
@@ -83,14 +86,14 @@ def serialize(self, headers: Dict[str, Union[str, List[str]]], cookies: List[Coo
8386

8487

8588
class SingleValueHeadersSerializer(BaseHeadersSerializer):
86-
def serialize(self, headers: Dict[str, Union[str, List[str]]], cookies: List[Cookie]) -> Dict[str, Any]:
89+
def serialize(self, headers: dict[str, str | list[str]], cookies: list[Cookie]) -> dict[str, Any]:
8790
"""
8891
The ALB integration has `multiValueHeaders` disabled by default.
8992
If we try to set multiple headers with the same key, or more than one cookie, print a warning.
9093
9194
https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html#respond-to-load-balancer
9295
"""
93-
payload: Dict[str, Dict[str, str]] = {}
96+
payload: dict[str, dict[str, str]] = {}
9497
payload.setdefault("headers", {})
9598

9699
if cookies:

0 commit comments

Comments
 (0)