Skip to content

Commit c865449

Browse files
refactor(data_classes): add from __future__ import annotations (aws-powertools#4939)
* refactor(data_classes): add from __future__ import annotations and update code according to ruff rules TCH, UP006, UP007, UP037 and FA100. * Fix subclassing Dict in Python 3.8 --------- Co-authored-by: Leandro Damascena <[email protected]>
1 parent 4688495 commit c865449

30 files changed

+442
-387
lines changed

aws_lambda_powertools/utilities/data_classes/active_mq_event.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
from __future__ import annotations
2+
13
from functools import cached_property
2-
from typing import Any, Dict, Iterator, Optional
4+
from typing import Any, Iterator
35

46
from aws_lambda_powertools.utilities.data_classes.common import DictWrapper
57
from aws_lambda_powertools.utilities.data_classes.shared_functions import base64_decode
@@ -62,32 +64,32 @@ def destination_physicalname(self) -> str:
6264
return self["destination"]["physicalName"]
6365

6466
@property
65-
def delivery_mode(self) -> Optional[int]:
67+
def delivery_mode(self) -> int | None:
6668
"""persistent or non-persistent delivery"""
6769
return self.get("deliveryMode")
6870

6971
@property
70-
def correlation_id(self) -> Optional[str]:
72+
def correlation_id(self) -> str | None:
7173
"""User defined correlation id"""
7274
return self.get("correlationID")
7375

7476
@property
75-
def reply_to(self) -> Optional[str]:
77+
def reply_to(self) -> str | None:
7678
"""User defined reply to"""
7779
return self.get("replyTo")
7880

7981
@property
80-
def get_type(self) -> Optional[str]:
82+
def get_type(self) -> str | None:
8183
"""User defined message type"""
8284
return self.get("type")
8385

8486
@property
85-
def expiration(self) -> Optional[int]:
87+
def expiration(self) -> int | None:
8688
"""Expiration attribute whose value is given in milliseconds"""
8789
return self.get("expiration")
8890

8991
@property
90-
def priority(self) -> Optional[int]:
92+
def priority(self) -> int | None:
9193
"""
9294
JMS defines a ten-level priority value, with 0 as the lowest priority and 9
9395
as the highest. In addition, clients should consider priorities 0-4 as
@@ -110,9 +112,9 @@ class ActiveMQEvent(DictWrapper):
110112
- https://aws.amazon.com/blogs/compute/using-amazon-mq-as-an-event-source-for-aws-lambda/
111113
"""
112114

113-
def __init__(self, data: Dict[str, Any]):
115+
def __init__(self, data: dict[str, Any]):
114116
super().__init__(data)
115-
self._messages: Optional[Iterator[ActiveMQMessage]] = None
117+
self._messages: Iterator[ActiveMQMessage] | None = None
116118

117119
@property
118120
def event_source(self) -> str:

aws_lambda_powertools/utilities/data_classes/alb_event.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
from typing import Any, Dict, List
1+
from __future__ import annotations
2+
3+
from typing import Any
24

35
from aws_lambda_powertools.shared.headers_serializer import (
46
BaseHeadersSerializer,
@@ -33,19 +35,19 @@ def request_context(self) -> ALBEventRequestContext:
3335
return ALBEventRequestContext(self._data)
3436

3537
@property
36-
def multi_value_query_string_parameters(self) -> Dict[str, List[str]]:
38+
def multi_value_query_string_parameters(self) -> dict[str, list[str]]:
3739
return self.get("multiValueQueryStringParameters") or {}
3840

3941
@property
40-
def resolved_query_string_parameters(self) -> Dict[str, List[str]]:
42+
def resolved_query_string_parameters(self) -> dict[str, list[str]]:
4143
return self.multi_value_query_string_parameters or super().resolved_query_string_parameters
4244

4345
@property
44-
def multi_value_headers(self) -> Dict[str, List[str]]:
46+
def multi_value_headers(self) -> dict[str, list[str]]:
4547
return CaseInsensitiveDict(self.get("multiValueHeaders"))
4648

4749
@property
48-
def resolved_headers_field(self) -> Dict[str, Any]:
50+
def resolved_headers_field(self) -> dict[str, Any]:
4951
return self.multi_value_headers or self.headers
5052

5153
def header_serializer(self) -> BaseHeadersSerializer:

aws_lambda_powertools/utilities/data_classes/api_gateway_authorizer_event.py

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
from __future__ import annotations
2+
13
import enum
24
import re
3-
from typing import Any, Dict, List, Optional
5+
from typing import Any
46

57
from aws_lambda_powertools.utilities.data_classes.common import (
68
BaseRequestContext,
@@ -141,19 +143,19 @@ def http_method(self) -> str:
141143
return self["httpMethod"]
142144

143145
@property
144-
def headers(self) -> Dict[str, str]:
146+
def headers(self) -> dict[str, str]:
145147
return CaseInsensitiveDict(self["headers"])
146148

147149
@property
148-
def query_string_parameters(self) -> Dict[str, str]:
150+
def query_string_parameters(self) -> dict[str, str]:
149151
return self["queryStringParameters"]
150152

151153
@property
152-
def path_parameters(self) -> Dict[str, str]:
154+
def path_parameters(self) -> dict[str, str]:
153155
return self["pathParameters"]
154156

155157
@property
156-
def stage_variables(self) -> Dict[str, str]:
158+
def stage_variables(self) -> dict[str, str]:
157159
return self["stageVariables"]
158160

159161
@property
@@ -193,7 +195,7 @@ def parsed_arn(self) -> APIGatewayRouteArn:
193195
return parse_api_gateway_arn(self.route_arn)
194196

195197
@property
196-
def identity_source(self) -> List[str]:
198+
def identity_source(self) -> list[str]:
197199
"""The identity source for which authorization is requested.
198200
199201
For a REQUEST authorizer, this is optional. The value is a set of one or more mapping expressions of the
@@ -217,29 +219,29 @@ def raw_query_string(self) -> str:
217219
return self["rawQueryString"]
218220

219221
@property
220-
def cookies(self) -> List[str]:
222+
def cookies(self) -> list[str]:
221223
"""Cookies"""
222224
return self["cookies"]
223225

224226
@property
225-
def headers(self) -> Dict[str, str]:
227+
def headers(self) -> dict[str, str]:
226228
"""Http headers"""
227229
return CaseInsensitiveDict(self["headers"])
228230

229231
@property
230-
def query_string_parameters(self) -> Dict[str, str]:
232+
def query_string_parameters(self) -> dict[str, str]:
231233
return self["queryStringParameters"]
232234

233235
@property
234236
def request_context(self) -> BaseRequestContextV2:
235237
return BaseRequestContextV2(self._data)
236238

237239
@property
238-
def path_parameters(self) -> Dict[str, str]:
240+
def path_parameters(self) -> dict[str, str]:
239241
return self.get("pathParameters") or {}
240242

241243
@property
242-
def stage_variables(self) -> Dict[str, str]:
244+
def stage_variables(self) -> dict[str, str]:
243245
return self.get("stageVariables") or {}
244246

245247

@@ -253,7 +255,7 @@ class APIGatewayAuthorizerResponseV2:
253255
is authorized to make calls to the GraphQL API. If this value is
254256
true, execution of the GraphQL API continues. If this value is false,
255257
an UnauthorizedException is raised
256-
context: Dict[str, Any], optional
258+
context: dict[str, Any], optional
257259
A JSON object visible as `event.requestContext.authorizer` lambda event
258260
259261
The context object only supports key-value pairs. Nested keys are not supported.
@@ -264,14 +266,14 @@ class APIGatewayAuthorizerResponseV2:
264266
def __init__(
265267
self,
266268
authorize: bool = False,
267-
context: Optional[Dict[str, Any]] = None,
269+
context: dict[str, Any] | None = None,
268270
):
269271
self.authorize = authorize
270272
self.context = context
271273

272274
def asdict(self) -> dict:
273275
"""Return the response as a dict"""
274-
response: Dict = {"isAuthorized": self.authorize}
276+
response: dict = {"isAuthorized": self.authorize}
275277

276278
if self.context:
277279
response["context"] = self.context
@@ -329,8 +331,8 @@ def __init__(
329331
aws_account_id: str,
330332
api_id: str,
331333
stage: str,
332-
context: Optional[Dict] = None,
333-
usage_identifier_key: Optional[str] = None,
334+
context: dict | None = None,
335+
usage_identifier_key: str | None = None,
334336
partition: str = "aws",
335337
):
336338
"""
@@ -357,7 +359,7 @@ def __init__(
357359
greedily expand over '/' or other separators.
358360
See https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_resource.html for more
359361
details.
360-
context : Dict, optional
362+
context : dict, optional
361363
Optional, context.
362364
Note: only names of type string and values of type int, string or boolean are supported
363365
usage_identifier_key: str, optional
@@ -375,18 +377,18 @@ def __init__(
375377
self.stage = stage
376378
self.context = context
377379
self.usage_identifier_key = usage_identifier_key
378-
self._allow_routes: List[Dict] = []
379-
self._deny_routes: List[Dict] = []
380+
self._allow_routes: list[dict] = []
381+
self._deny_routes: list[dict] = []
380382
self._resource_pattern = re.compile(self.path_regex)
381383
self.partition = partition
382384

383385
@staticmethod
384386
def from_route_arn(
385387
arn: str,
386388
principal_id: str,
387-
context: Optional[Dict] = None,
388-
usage_identifier_key: Optional[str] = None,
389-
) -> "APIGatewayAuthorizerResponse":
389+
context: dict | None = None,
390+
usage_identifier_key: str | None = None,
391+
) -> APIGatewayAuthorizerResponse:
390392
parsed_arn = parse_api_gateway_arn(arn)
391393
return APIGatewayAuthorizerResponse(
392394
principal_id,
@@ -398,7 +400,7 @@ def from_route_arn(
398400
usage_identifier_key,
399401
)
400402

401-
def _add_route(self, effect: str, http_method: str, resource: str, conditions: Optional[List[Dict]] = None):
403+
def _add_route(self, effect: str, http_method: str, resource: str, conditions: list[dict] | None = None):
402404
"""Adds a route to the internal lists of allowed or denied routes. Each object in
403405
the internal list contains a resource ARN and a condition statement. The condition
404406
statement can be null."""
@@ -427,17 +429,17 @@ def _add_route(self, effect: str, http_method: str, resource: str, conditions: O
427429
self._deny_routes.append(route)
428430

429431
@staticmethod
430-
def _get_empty_statement(effect: str) -> Dict[str, Any]:
432+
def _get_empty_statement(effect: str) -> dict[str, Any]:
431433
"""Returns an empty statement object prepopulated with the correct action and the desired effect."""
432434
return {"Action": "execute-api:Invoke", "Effect": effect.capitalize(), "Resource": []}
433435

434-
def _get_statement_for_effect(self, effect: str, routes: List[Dict]) -> List[Dict]:
436+
def _get_statement_for_effect(self, effect: str, routes: list[dict]) -> list[dict]:
435437
"""This function loops over an array of objects containing a `resourceArn` and
436438
`conditions` statement and generates the array of statements for the policy."""
437439
if not routes:
438440
return []
439441

440-
statements: List[Dict] = []
442+
statements: list[dict] = []
441443
statement = self._get_empty_statement(effect)
442444

443445
for route in routes:
@@ -476,31 +478,31 @@ def deny_all_routes(self, http_method: str = HttpVerb.ALL.value):
476478

477479
self._add_route(effect="Deny", http_method=http_method, resource="*")
478480

479-
def allow_route(self, http_method: str, resource: str, conditions: Optional[List[Dict]] = None):
481+
def allow_route(self, http_method: str, resource: str, conditions: list[dict] | None = None):
480482
"""Adds an API Gateway method (Http verb + Resource path) to the list of allowed
481483
methods for the policy.
482484
483485
Optionally includes a condition for the policy statement. More on AWS policy
484486
conditions here: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#Condition"""
485487
self._add_route(effect="Allow", http_method=http_method, resource=resource, conditions=conditions)
486488

487-
def deny_route(self, http_method: str, resource: str, conditions: Optional[List[Dict]] = None):
489+
def deny_route(self, http_method: str, resource: str, conditions: list[dict] | None = None):
488490
"""Adds an API Gateway method (Http verb + Resource path) to the list of denied
489491
methods for the policy.
490492
491493
Optionally includes a condition for the policy statement. More on AWS policy
492494
conditions here: https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements.html#Condition"""
493495
self._add_route(effect="Deny", http_method=http_method, resource=resource, conditions=conditions)
494496

495-
def asdict(self) -> Dict[str, Any]:
497+
def asdict(self) -> dict[str, Any]:
496498
"""Generates the policy document based on the internal lists of allowed and denied
497499
conditions. This will generate a policy with two main statements for the effect:
498500
one statement for Allow and one statement for Deny.
499501
Methods that includes conditions will have their own statement in the policy."""
500502
if len(self._allow_routes) == 0 and len(self._deny_routes) == 0:
501503
raise ValueError("No statements defined for the policy")
502504

503-
response: Dict[str, Any] = {
505+
response: dict[str, Any] = {
504506
"principalId": self.principal_id,
505507
"policyDocument": {"Version": "2012-10-17", "Statement": []},
506508
}

0 commit comments

Comments
 (0)