Skip to content

Commit 2989ec1

Browse files
refactor(logging): add from __future__ import annotations (#4940)
* refactor(logging): add from __future__ import annotations and update code according to ruff rules TCH, UP006, UP007, UP037 and FA100. * Prefer absolute imports * Fix type alias with Python 3.8 See https://bugs.python.org/issue45117 --------- Co-authored-by: Leandro Damascena <[email protected]>
1 parent b0006dd commit 2989ec1

File tree

5 files changed

+105
-100
lines changed

5 files changed

+105
-100
lines changed

aws_lambda_powertools/logging/formatter.py

+19-17
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@
99
from abc import ABCMeta, abstractmethod
1010
from datetime import datetime, timezone
1111
from functools import partial
12-
from typing import Any, Callable, Dict, Iterable, List, Optional, Tuple, Union
12+
from typing import TYPE_CHECKING, Any, Callable, Iterable
1313

14-
from aws_lambda_powertools.logging.types import LogRecord, LogStackTrace
1514
from aws_lambda_powertools.shared import constants
1615
from aws_lambda_powertools.shared.functions import powertools_dev_is_set
1716

17+
if TYPE_CHECKING:
18+
from aws_lambda_powertools.logging.types import LogRecord, LogStackTrace
19+
1820
RESERVED_LOG_ATTRS = (
1921
"name",
2022
"msg",
@@ -48,7 +50,7 @@ class BasePowertoolsFormatter(logging.Formatter, metaclass=ABCMeta):
4850
def append_keys(self, **additional_keys) -> None:
4951
raise NotImplementedError()
5052

51-
def get_current_keys(self) -> Dict[str, Any]:
53+
def get_current_keys(self) -> dict[str, Any]:
5254
return {}
5355

5456
def remove_keys(self, keys: Iterable[str]) -> None:
@@ -74,11 +76,11 @@ class LambdaPowertoolsFormatter(BasePowertoolsFormatter):
7476
def __init__(
7577
self,
7678
json_serializer: Callable[[LogRecord], str] | None = None,
77-
json_deserializer: Callable[[Dict | str | bool | int | float], str] | None = None,
79+
json_deserializer: Callable[[dict | str | bool | int | float], str] | None = None,
7880
json_default: Callable[[Any], Any] | None = None,
7981
datefmt: str | None = None,
8082
use_datetime_directive: bool = False,
81-
log_record_order: List[str] | None = None,
83+
log_record_order: list[str] | None = None,
8284
utc: bool = False,
8385
use_rfc3339: bool = False,
8486
serialize_stacktrace: bool = True,
@@ -182,7 +184,7 @@ def format(self, record: logging.LogRecord) -> str: # noqa: A003
182184

183185
return self.serialize(log=formatted_log)
184186

185-
def formatTime(self, record: logging.LogRecord, datefmt: Optional[str] = None) -> str:
187+
def formatTime(self, record: logging.LogRecord, datefmt: str | None = None) -> str:
186188
# As of Py3.7, we can infer milliseconds directly from any datetime
187189
# saving processing time as we can shortcircuit early
188190
# Maintenance: In V3, we (and Java) should move to this format by default
@@ -234,7 +236,7 @@ def formatTime(self, record: logging.LogRecord, datefmt: Optional[str] = None) -
234236
def append_keys(self, **additional_keys) -> None:
235237
self.log_format.update(additional_keys)
236238

237-
def get_current_keys(self) -> Dict[str, Any]:
239+
def get_current_keys(self) -> dict[str, Any]:
238240
return self.log_format
239241

240242
def remove_keys(self, keys: Iterable[str]) -> None:
@@ -246,14 +248,14 @@ def clear_state(self) -> None:
246248
self.log_format.update(**self.keys_combined)
247249

248250
@staticmethod
249-
def _build_default_keys() -> Dict[str, str]:
251+
def _build_default_keys() -> dict[str, str]:
250252
return {
251253
"level": "%(levelname)s",
252254
"location": "%(funcName)s:%(lineno)d",
253255
"timestamp": "%(asctime)s",
254256
}
255257

256-
def _get_latest_trace_id(self) -> Optional[str]:
258+
def _get_latest_trace_id(self) -> str | None:
257259
xray_trace_id_key = self.log_format.get("xray_trace_id", "")
258260
if xray_trace_id_key is None:
259261
# key is explicitly disabled; ignore it. e.g., Logger(xray_trace_id=None)
@@ -262,7 +264,7 @@ def _get_latest_trace_id(self) -> Optional[str]:
262264
xray_trace_id = os.getenv(constants.XRAY_TRACE_ID_ENV)
263265
return xray_trace_id.split(";")[0].replace("Root=", "") if xray_trace_id else None
264266

265-
def _extract_log_message(self, log_record: logging.LogRecord) -> Union[Dict[str, Any], str, bool, Iterable]:
267+
def _extract_log_message(self, log_record: logging.LogRecord) -> dict[str, Any] | str | bool | Iterable:
266268
"""Extract message from log record and attempt to JSON decode it if str
267269
268270
Parameters
@@ -272,7 +274,7 @@ def _extract_log_message(self, log_record: logging.LogRecord) -> Union[Dict[str,
272274
273275
Returns
274276
-------
275-
message: Union[Dict, str, bool, Iterable]
277+
message: dict[str, Any] | str | bool | Iterable
276278
Extracted message
277279
"""
278280
message = log_record.msg
@@ -308,7 +310,7 @@ def _serialize_stacktrace(self, log_record: logging.LogRecord) -> LogStackTrace
308310

309311
return None
310312

311-
def _extract_log_exception(self, log_record: logging.LogRecord) -> Union[Tuple[str, str], Tuple[None, None]]:
313+
def _extract_log_exception(self, log_record: logging.LogRecord) -> tuple[str, str] | tuple[None, None]:
312314
"""Format traceback information, if available
313315
314316
Parameters
@@ -318,15 +320,15 @@ def _extract_log_exception(self, log_record: logging.LogRecord) -> Union[Tuple[s
318320
319321
Returns
320322
-------
321-
log_record: Optional[Tuple[str, str]]
323+
log_record: tuple[str, str] | tuple[None, None]
322324
Log record with constant traceback info and exception name
323325
"""
324326
if log_record.exc_info:
325327
return self.formatException(log_record.exc_info), log_record.exc_info[0].__name__ # type: ignore
326328

327329
return None, None
328330

329-
def _extract_log_keys(self, log_record: logging.LogRecord) -> Dict[str, Any]:
331+
def _extract_log_keys(self, log_record: logging.LogRecord) -> dict[str, Any]:
330332
"""Extract and parse custom and reserved log keys
331333
332334
Parameters
@@ -336,7 +338,7 @@ def _extract_log_keys(self, log_record: logging.LogRecord) -> Dict[str, Any]:
336338
337339
Returns
338340
-------
339-
formatted_log: Dict
341+
formatted_log: dict[str, Any]
340342
Structured log as dictionary
341343
"""
342344
record_dict = log_record.__dict__.copy()
@@ -358,7 +360,7 @@ def _extract_log_keys(self, log_record: logging.LogRecord) -> Dict[str, Any]:
358360
return formatted_log
359361

360362
@staticmethod
361-
def _strip_none_records(records: Dict[str, Any]) -> Dict[str, Any]:
363+
def _strip_none_records(records: dict[str, Any]) -> dict[str, Any]:
362364
"""Remove any key with None as value"""
363365
return {k: v for k, v in records.items() if v is not None}
364366

@@ -367,4 +369,4 @@ def _strip_none_records(records: Dict[str, Any]) -> Dict[str, Any]:
367369

368370

369371
# Fetch current and future parameters from PowertoolsFormatter that should be reserved
370-
RESERVED_FORMATTER_CUSTOM_KEYS: List[str] = inspect.getfullargspec(LambdaPowertoolsFormatter).args[1:]
372+
RESERVED_FORMATTER_CUSTOM_KEYS: list[str] = inspect.getfullargspec(LambdaPowertoolsFormatter).args[1:]

aws_lambda_powertools/logging/formatters/datadog.py

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

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

55
from aws_lambda_powertools.logging.formatter import LambdaPowertoolsFormatter
6-
from aws_lambda_powertools.logging.types import LogRecord
6+
7+
if TYPE_CHECKING:
8+
from aws_lambda_powertools.logging.types import LogRecord
79

810

911
class DatadogLogFormatter(LambdaPowertoolsFormatter):
1012
def __init__(
1113
self,
1214
json_serializer: Callable[[LogRecord], str] | None = None,
13-
json_deserializer: Callable[[Dict | str | bool | int | float], str] | None = None,
15+
json_deserializer: Callable[[dict | str | bool | int | float], str] | None = None,
1416
json_default: Callable[[Any], Any] | None = None,
1517
datefmt: str | None = None,
1618
use_datetime_directive: bool = False,

0 commit comments

Comments
 (0)