Skip to content

Commit 85d5253

Browse files
authored
refactor(typing): enable TCH, UP and FA100 ruff rules (#5017)
* refactor(typing): enable TCH, UP and FA100 ruff rules * Fix missing ruff error TCH002 from data_classes
1 parent c865449 commit 85d5253

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+63
-82
lines changed

aws_lambda_powertools/__init__.py

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# -*- coding: utf-8 -*-
2-
31
"""Top-level package for Lambda Python Powertools."""
42

53
from pathlib import Path

aws_lambda_powertools/event_handler/api_gateway.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1870,7 +1870,7 @@ def route(
18701870

18711871
def register_resolver(func: Callable):
18721872
methods = (method,) if isinstance(method, str) else method
1873-
logger.debug(f"Adding route using rule {rule} and methods: {','.join((m.upper() for m in methods))}")
1873+
logger.debug(f"Adding route using rule {rule} and methods: {','.join(m.upper() for m in methods)}")
18741874

18751875
cors_enabled = self._cors_enabled if cors is None else cors
18761876

aws_lambda_powertools/event_handler/bedrock_agent.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ def get( # type: ignore[override]
109109
) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
110110
security = None
111111

112-
return super(BedrockAgentResolver, self).get(
112+
return super().get(
113113
rule,
114114
cors,
115115
compress,

aws_lambda_powertools/event_handler/openapi/params.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ def __init__(
328328
if default is not ...:
329329
raise AssertionError("Path parameters cannot have a default value")
330330

331-
super(Path, self).__init__(
331+
super().__init__(
332332
default=default,
333333
default_factory=default_factory,
334334
annotation=annotation,

aws_lambda_powertools/event_handler/openapi/types.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
import types
44
from enum import Enum
5-
from typing import Any, Callable, Dict, Set, Type, TypedDict, Union
5+
from typing import TYPE_CHECKING, Any, Callable, Dict, Set, Type, TypedDict, Union
66

77
from pydantic import BaseModel
8-
from typing_extensions import NotRequired
8+
9+
if TYPE_CHECKING:
10+
from typing_extensions import NotRequired
911

1012
CacheKey = Union[Callable[..., Any], None]
1113
IncEx = Union[Set[int], Set[str], Dict[int, Any], Dict[str, Any]]

aws_lambda_powertools/logging/types.py

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

3-
from typing import Any, Dict, TypedDict, Union
3+
from typing import TYPE_CHECKING, Any, Dict, TypedDict, Union
44

5-
from typing_extensions import NotRequired, TypeAlias
5+
if TYPE_CHECKING:
6+
from typing_extensions import NotRequired, TypeAlias
67

78

89
class PowertoolsLogRecord(TypedDict):

aws_lambda_powertools/metrics/provider/cloudwatch_emf/types.py

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

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

5-
from typing_extensions import NotRequired
5+
if TYPE_CHECKING:
6+
from typing_extensions import NotRequired
67

78

89
class CloudWatchEMFMetric(TypedDict):

aws_lambda_powertools/shared/cache_dict.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def __setitem__(self, key, value):
2525
del self[oldest]
2626

2727
def get(self, key, *args, **kwargs):
28-
item = super(LRUDict, self).get(key, *args, **kwargs)
28+
item = super().get(key, *args, **kwargs)
2929
if item:
3030
self.move_to_end(key=key)
3131
return item

aws_lambda_powertools/shared/lazy_import.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def __init__(self, local_name, parent_module_globals, name): # pylint: disable=
3232
self._local_name = local_name
3333
self._parent_module_globals = parent_module_globals
3434

35-
super(LazyLoader, self).__init__(name)
35+
super().__init__(name)
3636

3737
def _load(self):
3838
# Import the target module and insert it into the parent's namespace
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
# -*- coding: utf-8 -*-
2-
31
"""General utilities for Powertools"""

aws_lambda_powertools/utilities/batch/__init__.py

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# -*- coding: utf-8 -*-
2-
31
"""
42
Batch processing utility
53
"""

aws_lambda_powertools/utilities/batch/base.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
# -*- coding: utf-8 -*-
21
"""
32
Batch processing utilities
43
"""
4+
55
from __future__ import annotations
66

77
import asyncio

aws_lambda_powertools/utilities/batch/exceptions.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ def __init__(self, msg="", child_exceptions: list[ExceptionInfo] | None = None):
3434
super().__init__(msg, child_exceptions)
3535

3636
def __str__(self):
37-
parent_exception_str = super(BatchProcessingError, self).__str__()
37+
parent_exception_str = super().__str__()
3838
return self.format_exceptions(parent_exception_str)
3939

4040

aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py

+4-3
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@
55
import warnings
66
from dataclasses import dataclass, field
77
from functools import cached_property
8-
from typing import Any, Callable, ClassVar, Iterator
9-
10-
from typing_extensions import Literal
8+
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Iterator
119

1210
from aws_lambda_powertools.utilities.data_classes.common import DictWrapper
1311

12+
if TYPE_CHECKING:
13+
from typing_extensions import Literal
14+
1415

1516
@dataclass(repr=False, order=False, frozen=True)
1617
class KinesisFirehoseDataTransformationRecordMetadata:

aws_lambda_powertools/utilities/feature_flags/feature_flags.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,11 @@
1414
compare_time_range,
1515
)
1616
from aws_lambda_powertools.utilities.feature_flags.exceptions import ConfigurationStoreError
17-
from aws_lambda_powertools.utilities.feature_flags.types import P, T
1817

1918
if TYPE_CHECKING:
2019
from aws_lambda_powertools.logging import Logger
2120
from aws_lambda_powertools.utilities.feature_flags.base import StoreProvider
22-
from aws_lambda_powertools.utilities.feature_flags.types import JSONType
21+
from aws_lambda_powertools.utilities.feature_flags.types import JSONType, P, T
2322

2423

2524
RULE_ACTION_MAPPING = {

aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def __init__(
123123

124124
self._deserializer = TypeDeserializer()
125125

126-
super(DynamoDBPersistenceLayer, self).__init__()
126+
super().__init__()
127127

128128
def _get_key(self, idempotency_key: str) -> dict:
129129
"""Build primary key attribute simple or composite based on params.

aws_lambda_powertools/utilities/idempotency/persistence/redis.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,7 @@ def lambda_handler(event: dict, context: LambdaContext):
310310
self.validation_key_attr = validation_key_attr
311311
self._json_serializer = json.dumps
312312
self._json_deserializer = json.loads
313-
super(RedisCachePersistenceLayer, self).__init__()
313+
super().__init__()
314314
self._orphan_lock_timeout = min(10, self.expires_after_seconds)
315315

316316
def _get_expiry_second(self, expiry_timestamp: int | None = None) -> int:

aws_lambda_powertools/utilities/parameters/__init__.py

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# -*- coding: utf-8 -*-
2-
31
"""
42
Parameter retrieval and caching utility
53
"""

aws_lambda_powertools/utilities/typing/__init__.py

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
# -*- coding: utf-8 -*-
2-
31
"""
42
Typing for developer ease in the IDE
53
"""

aws_lambda_powertools/utilities/typing/lambda_client_context.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# -*- coding: utf-8 -*-
21
from __future__ import annotations
32

43
from typing import TYPE_CHECKING, Any
@@ -9,7 +8,7 @@
98
)
109

1110

12-
class LambdaClientContext(object):
11+
class LambdaClientContext:
1312
_client: LambdaClientContextMobileClient
1413
_custom: dict[str, Any]
1514
_env: dict[str, Any]

aws_lambda_powertools/utilities/typing/lambda_client_context_mobile_client.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
# -*- coding: utf-8 -*-
2-
3-
4-
class LambdaClientContextMobileClient(object):
1+
class LambdaClientContextMobileClient:
52
"""Mobile Client context that's provided to Lambda by the client application."""
63

74
_installation_id: str

aws_lambda_powertools/utilities/typing/lambda_cognito_identity.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
# -*- coding: utf-8 -*-
2-
3-
4-
class LambdaCognitoIdentity(object):
1+
class LambdaCognitoIdentity:
52
"""Information about the Amazon Cognito identity that authorized the request."""
63

74
_cognito_identity_id: str

aws_lambda_powertools/utilities/typing/lambda_context.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
# -*- coding: utf-8 -*-
21
from __future__ import annotations
32

43
from typing import TYPE_CHECKING
@@ -12,7 +11,7 @@
1211
)
1312

1413

15-
class LambdaContext(object):
14+
class LambdaContext:
1615
"""The LambdaContext static object can be used to ease the development by providing the IDE type hints.
1716
1817
Example

docs/utilities/batch.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ Use the context manager to access a list of all returned values from your `recor
502502

503503
=== "Accessing raw processed messages"
504504

505-
```python hl_lines="29-36"
505+
```python hl_lines="28-35"
506506
--8<-- "examples/batch_processing/src/context_manager_access.py"
507507
```
508508

examples/batch_processing/src/context_manager_access.py

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

33
import json
4-
from typing import List, Tuple
54

65
from typing_extensions import Literal
76

@@ -28,7 +27,7 @@ def record_handler(record: SQSRecord):
2827
def lambda_handler(event, context: LambdaContext):
2928
batch = event["Records"] # (1)!
3029
with processor(records=batch, handler=record_handler):
31-
processed_messages: List[Tuple] = processor.process()
30+
processed_messages: list[tuple] = processor.process()
3231

3332
for message in processed_messages:
3433
status: Literal["success", "fail"] = message[0]

examples/idempotency/src/bring_your_own_persistent_store.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def __init__(
3636
self.status_attr = status_attr
3737
self.data_attr = data_attr
3838
self.validation_key_attr = validation_key_attr
39-
super(MyOwnPersistenceLayer, self).__init__()
39+
super().__init__()
4040

4141
def _item_to_data_record(self, item: Dict[str, Any]) -> DataRecord:
4242
"""

ruff.toml

+8-3
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,9 @@ lint.select = [
2323
"Q", # flake8-quotes - https://beta.ruff.rs/docs/rules/#flake8-quotes-q
2424
"PTH", # flake8-use-pathlib - https://beta.ruff.rs/docs/rules/#flake8-use-pathlib-pth
2525
"T10", # flake8-debugger https://beta.ruff.rs/docs/rules/#flake8-debugger-t10
26+
"TCH", # flake8-type-checking - https://docs.astral.sh/ruff/rules/#flake8-type-checking-tch
2627
"TD", # flake8-todo - https://beta.ruff.rs/docs/rules/#flake8-todos-td
28+
"UP", # pyupgrade - https://docs.astral.sh/ruff/rules/#pyupgrade-up
2729
"W", # pycodestyle warning - https://beta.ruff.rs/docs/rules/#warning-w
2830
]
2931

@@ -36,7 +38,6 @@ lint.ignore = [
3638
"B904", # raise-without-from-inside-except - disabled temporarily
3739
"PLC1901", # Compare-to-empty-string - disabled temporarily
3840
"PYI024",
39-
"FA100", # Enable this rule when drop support to Python 3.7
4041
]
4142

4243
# Exclude files and directories
@@ -58,6 +59,7 @@ exclude = [
5859
# Maximum line length
5960
line-length = 120
6061

62+
target-version = "py38"
6163

6264
fix = true
6365
lint.fixable = ["I", "COM812", "W"]
@@ -81,6 +83,9 @@ max-statements = 70
8183
[lint.isort]
8284
split-on-trailing-comma = true
8385

86+
[lint.flake8-type-checking]
87+
runtime-evaluated-base-classes = ["pydantic.BaseModel"]
88+
8489
[lint.per-file-ignores]
8590
# Ignore specific rules for specific files
8691
"tests/e2e/utils/data_builder/__init__.py" = ["F401"]
@@ -90,6 +95,6 @@ split-on-trailing-comma = true
9095
"aws_lambda_powertools/event_handler/openapi/compat.py" = ["F401"]
9196
# Maintenance: we're keeping EphemeralMetrics code in case of Hyrum's law so we can quickly revert it
9297
"aws_lambda_powertools/metrics/metrics.py" = ["ERA001"]
93-
"examples/*" = ["FA100"]
94-
"tests/*" = ["FA100"]
98+
"examples/*" = ["FA100", "TCH"]
99+
"tests/*" = ["FA100", "TCH"]
95100
"aws_lambda_powertools/utilities/parser/models/*" = ["FA100"]

tests/e2e/parser/handlers/handler_with_union_tag.py

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
from __future__ import annotations
2-
31
from typing import Literal, Union
42

53
from pydantic import BaseModel, Field

tests/functional/data_masking/test_aws_encryption_sdk.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
1-
from __future__ import annotations
2-
31
import base64
42
import functools
53
import json
6-
from typing import Any, Callable
4+
from typing import Any, Callable, Union
75

86
import pytest
97
from aws_encryption_sdk.identifiers import Algorithm
@@ -24,7 +22,7 @@ def __init__(
2422
) -> None:
2523
super().__init__(json_serializer, json_deserializer)
2624

27-
def encrypt(self, data: bytes | str, **kwargs) -> str:
25+
def encrypt(self, data: Union[bytes, str], **kwargs) -> str:
2826
encoded_data: str = self.json_serializer(data)
2927
ciphertext = base64.b64encode(encoded_data.encode("utf-8")).decode()
3028
return ciphertext

tests/functional/event_handler/test_openapi_serialization.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def serializer(_):
4848
app = APIGatewayRestResolver(enable_validation=True, serializer=serializer)
4949

5050
# GIVEN a custom class
51-
class CustomClass(object):
51+
class CustomClass:
5252
__slots__ = []
5353

5454
# GIVEN a handler that returns an instance of that class

tests/functional/idempotency/persistence/test_redis_layer.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def __init__(self, cache: dict = None, mock_latency_ms: int = 0, **kwargs):
100100
self.closed = False
101101
self.mock_latency_ms = mock_latency_ms
102102
self.nx_lock = Lock()
103-
super(MockRedis, self).__init__()
103+
super().__init__()
104104

105105
# check_closed is called before every mock redis operation
106106
def check_closed(self):

tests/functional/idempotency/test_idempotency.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1179,7 +1179,7 @@ def handler(event, context):
11791179
class MockPersistenceLayer(BasePersistenceLayer):
11801180
def __init__(self, expected_idempotency_key: str):
11811181
self.expected_idempotency_key = expected_idempotency_key
1182-
super(MockPersistenceLayer, self).__init__()
1182+
super().__init__()
11831183

11841184
def _put_record(self, data_record: DataRecord) -> None:
11851185
assert data_record.idempotency_key == self.expected_idempotency_key

tests/functional/idempotency/utils.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
1-
from __future__ import annotations
2-
31
import hashlib
42
import json
5-
from typing import Any, Dict
3+
from typing import Any, Dict, Optional
64

75
from botocore import stub
86
from pytest import FixtureRequest
@@ -90,7 +88,7 @@ def build_idempotency_put_item_response_stub(
9088
expiration: int,
9189
status: str,
9290
request: FixtureRequest,
93-
validation_data: Any | None,
91+
validation_data: Optional[Any],
9492
):
9593
response = {
9694
"Item": {

0 commit comments

Comments
 (0)