Skip to content

Commit

Permalink
chore(ci): drop support for Python 3.7 (#3638)
Browse files Browse the repository at this point in the history
* Python 3.7 deprecation + cleaning code with unnecessary compats

* Ops, missing a file

* Ops, missing a file

* Reverting a potential breaking change

* Refactoring data class to cache some properties

* Importing from typing_extensions directly

* Reverting

* Addressing Heitor's feedback

---------

Co-authored-by: Heitor Lessa <[email protected]>
  • Loading branch information
leandrodamascena and heitorlessa authored Feb 5, 2024
1 parent 190e9a9 commit 95d8eda
Show file tree
Hide file tree
Showing 39 changed files with 67 additions and 436 deletions.
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ body:
attributes:
label: AWS Lambda function runtime
options:
- "3.7"
- "3.8"
- "3.9"
- "3.10"
Expand Down
1 change: 0 additions & 1 deletion .github/ISSUE_TEMPLATE/static_typing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ body:
attributes:
label: AWS Lambda function runtime
options:
- "3.7"
- "3.8"
- "3.9"
- "3.10"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/quality_check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
env:
PYTHON: "${{ matrix.python-version }}"
permissions:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/quality_check_pydanticv2.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
strategy:
max-parallel: 4
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
env:
PYTHON: "${{ matrix.python-version }}"
permissions:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/run-e2e-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
strategy:
fail-fast: false # needed so if a version fails, the others will still be able to complete and cleanup
matrix:
version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
if: ${{ github.actor != 'dependabot[bot]' && github.repository == 'aws-powertools/powertools-lambda-python' }}
steps:
- name: "Checkout"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

[![Build](https://github.com/aws-powertools/powertools-lambda-python/actions/workflows/quality_check.yml/badge.svg)](https://github.com/aws-powertools/powertools-lambda-python/actions/workflows/python_build.yml)
[![codecov.io](https://codecov.io/github/aws-powertools/powertools-lambda-python/branch/develop/graphs/badge.svg)](https://app.codecov.io/gh/aws-powertools/powertools-lambda-python)
![PythonSupport](https://img.shields.io/static/v1?label=python&message=%203.7|%203.8|%203.9|%203.10|%203.11|%203.12&color=blue?style=flat-square&logo=python) ![PyPI version](https://badge.fury.io/py/aws-lambda-powertools.svg) ![PyPi monthly downloads](https://img.shields.io/pypi/dm/aws-lambda-powertools) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/aws-powertools/powertools-lambda-python/badge)](https://api.securityscorecards.dev/projects/github.com/aws-powertools/powertools-lambda-python) [![Join our Discord](https://dcbadge.vercel.app/api/server/B8zZKbbyET)](https://discord.gg/B8zZKbbyET)
![PythonSupport](https://img.shields.io/static/v1?label=python&message=%203.8|%203.9|%203.10|%203.11|%203.12&color=blue?style=flat-square&logo=python) ![PyPI version](https://badge.fury.io/py/aws-lambda-powertools.svg) ![PyPi monthly downloads](https://img.shields.io/pypi/dm/aws-lambda-powertools) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/aws-powertools/powertools-lambda-python/badge)](https://api.securityscorecards.dev/projects/github.com/aws-powertools/powertools-lambda-python) [![Join our Discord](https://dcbadge.vercel.app/api/server/B8zZKbbyET)](https://discord.gg/B8zZKbbyET)

Powertools for AWS Lambda (Python) is a developer toolkit to implement Serverless [best practices and increase developer velocity](https://docs.powertools.aws.dev/lambda/python/latest/#features).

Expand Down
51 changes: 0 additions & 51 deletions aws_lambda_powertools/logging/compat.py

This file was deleted.

22 changes: 0 additions & 22 deletions aws_lambda_powertools/logging/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
overload,
)

from aws_lambda_powertools.logging import compat
from aws_lambda_powertools.shared import constants
from aws_lambda_powertools.shared.functions import (
extract_event_from_common_models,
Expand Down Expand Up @@ -302,9 +301,6 @@ def _init_logger(
self.addHandler(self.logger_handler)
self.structure_logs(formatter_options=formatter_options, **kwargs)

# Maintenance: We can drop this upon Py3.7 EOL. It's a backport for "location" key to work
self._logger.findCaller = compat.findCaller # type: ignore[method-assign]

# Pytest Live Log feature duplicates log records for colored output
# but we explicitly add a filter for log deduplication.
# This flag disables this protection when you explicit want logs to be duplicated (#262)
Expand Down Expand Up @@ -467,9 +463,6 @@ def info(
extra = extra or {}
extra = {**extra, **kwargs}

# Maintenance: We can drop this upon Py3.7 EOL. It's a backport for "location" key to work
if sys.version_info < (3, 8): # pragma: no cover
return self._logger.info(msg, *args, exc_info=exc_info, stack_info=stack_info, extra=extra)
return self._logger.info(
msg,
*args,
Expand All @@ -492,9 +485,6 @@ def error(
extra = extra or {}
extra = {**extra, **kwargs}

# Maintenance: We can drop this upon Py3.7 EOL. It's a backport for "location" key to work
if sys.version_info < (3, 8): # pragma: no cover
return self._logger.error(msg, *args, exc_info=exc_info, stack_info=stack_info, extra=extra)
return self._logger.error(
msg,
*args,
Expand All @@ -517,9 +507,6 @@ def exception(
extra = extra or {}
extra = {**extra, **kwargs}

# Maintenance: We can drop this upon Py3.7 EOL. It's a backport for "location" key to work
if sys.version_info < (3, 8): # pragma: no cover
return self._logger.exception(msg, *args, exc_info=exc_info, stack_info=stack_info, extra=extra)
return self._logger.exception(
msg,
*args,
Expand All @@ -542,9 +529,6 @@ def critical(
extra = extra or {}
extra = {**extra, **kwargs}

# Maintenance: We can drop this upon Py3.7 EOL. It's a backport for "location" key to work
if sys.version_info < (3, 8): # pragma: no cover
return self._logger.critical(msg, *args, exc_info=exc_info, stack_info=stack_info, extra=extra)
return self._logger.critical(
msg,
*args,
Expand All @@ -567,9 +551,6 @@ def warning(
extra = extra or {}
extra = {**extra, **kwargs}

# Maintenance: We can drop this upon Py3.7 EOL. It's a backport for "location" key to work
if sys.version_info < (3, 8): # pragma: no cover
return self._logger.warning(msg, *args, exc_info=exc_info, stack_info=stack_info, extra=extra)
return self._logger.warning(
msg,
*args,
Expand All @@ -592,9 +573,6 @@ def debug(
extra = extra or {}
extra = {**extra, **kwargs}

# Maintenance: We can drop this upon Py3.7 EOL. It's a backport for "location" key to work
if sys.version_info < (3, 8): # pragma: no cover
return self._logger.debug(msg, *args, exc_info=exc_info, stack_info=stack_info, extra=extra)
return self._logger.debug(
msg,
*args,
Expand Down
8 changes: 1 addition & 7 deletions aws_lambda_powertools/shared/types.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import sys
from typing import Any, Callable, Dict, List, TypeVar, Union

if sys.version_info >= (3, 8):
from typing import Literal, Protocol, TypedDict
else:
from typing_extensions import Literal, Protocol, TypedDict
from typing import Any, Callable, Dict, List, Literal, Protocol, TypedDict, TypeVar, Union

if sys.version_info >= (3, 9):
from typing import Annotated
Expand All @@ -16,7 +11,6 @@
else:
from typing_extensions import NotRequired


# Even though `get_args` and `get_origin` were added in Python 3.8, they only handle Annotated correctly on 3.10.
# So for python < 3.10 we use the backport from typing_extensions.
if sys.version_info >= (3, 10):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from functools import cached_property
from typing import Any, Dict, Iterator, Optional

from aws_lambda_powertools.utilities.data_classes.common import DictWrapper
Expand All @@ -23,12 +24,9 @@ def decoded_data(self) -> str:
"""Decodes the data as a str"""
return base64_decode(self.data)

@property
@cached_property
def json_data(self) -> Any:
"""Parses the data as json"""
if self._json_data is None:
self._json_data = self._json_deserializer(self.decoded_data)
return self._json_data
return self._json_deserializer(self.decoded_data)

@property
def connection_id(self) -> str:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import tempfile
import zipfile
from functools import cached_property
from typing import Any, Dict, List, Optional
from urllib.parse import unquote_plus

Expand All @@ -17,12 +18,13 @@ def user_parameters(self) -> Optional[str]:
"""User parameters"""
return self.get("UserParameters", None)

@property
@cached_property
def decoded_user_parameters(self) -> Optional[Dict[str, Any]]:
"""Json Decoded user parameters"""
if self._json_data is None and self.user_parameters is not None:
self._json_data = self._json_deserializer(self.user_parameters)
return self._json_data
if self.user_parameters is not None:
return self._json_deserializer(self.user_parameters)

return None


class CodePipelineActionConfiguration(DictWrapper):
Expand Down
10 changes: 4 additions & 6 deletions aws_lambda_powertools/utilities/data_classes/common.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import base64
import json
from collections.abc import Mapping
from functools import cached_property
from typing import Any, Callable, Dict, Iterator, List, Optional, overload

from aws_lambda_powertools.shared.headers_serializer import BaseHeadersSerializer
Expand All @@ -24,7 +25,6 @@ def __init__(self, data: Dict[str, Any], json_deserializer: Optional[Callable] =
by default json.loads
"""
self._data = data
self._json_data: Optional[Any] = None
self._json_deserializer = json_deserializer or json.loads

def __getitem__(self, key: str) -> Any:
Expand Down Expand Up @@ -138,14 +138,12 @@ def body(self) -> Optional[str]:
"""Submitted body of the request as a string"""
return self.get("body")

@property
@cached_property
def json_body(self) -> Any:
"""Parses the submitted body as json"""
if self._json_data is None:
self._json_data = self._json_deserializer(self.decoded_body)
return self._json_data
return self._json_deserializer(self.decoded_body)

@property
@cached_property
def decoded_body(self) -> str:
"""Dynamically base64 decode body as a str"""
body: str = self["body"]
Expand Down
7 changes: 3 additions & 4 deletions aws_lambda_powertools/utilities/data_classes/kafka_event.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import base64
from functools import cached_property
from typing import Any, Dict, Iterator, List, Optional

from aws_lambda_powertools.utilities.data_classes.common import DictWrapper
Expand Down Expand Up @@ -53,12 +54,10 @@ def decoded_value(self) -> bytes:
"""Decodes the base64 encoded value as bytes."""
return base64.b64decode(self.value)

@property
@cached_property
def json_value(self) -> Any:
"""Decodes the text encoded data as JSON."""
if self._json_data is None:
self._json_data = self._json_deserializer(self.decoded_value.decode("utf-8"))
return self._json_data
return self._json_deserializer(self.decoded_value.decode("utf-8"))

@property
def headers(self) -> List[Dict[str, List[int]]]:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import json
import warnings
from dataclasses import dataclass, field
from functools import cached_property
from typing import Any, Callable, ClassVar, Dict, Iterator, List, Optional, Tuple

from typing_extensions import Literal
Expand Down Expand Up @@ -70,7 +71,6 @@ class KinesisFirehoseDataTransformationRecord:
metadata: Optional[KinesisFirehoseDataTransformationRecordMetadata] = None
json_serializer: Callable = json.dumps
json_deserializer: Callable = json.loads
_json_data: Optional[Any] = None

def asdict(self) -> Dict:
if self.result not in self._valid_result_types:
Expand Down Expand Up @@ -102,14 +102,13 @@ def data_as_text(self) -> str:
return ""
return self.data_as_bytes.decode("utf-8")

@property
@cached_property
def data_as_json(self) -> Dict:
"""Decoded base64-encoded data loaded to json"""
if not self.data:
return {}
if self._json_data is None:
self._json_data = self.json_deserializer(self.data_as_text)
return self._json_data

return self.json_deserializer(self.data_as_text)


@dataclass(repr=False, order=False)
Expand Down Expand Up @@ -240,12 +239,10 @@ def data_as_text(self) -> str:
"""Decoded base64-encoded data as text"""
return self.data_as_bytes.decode("utf-8")

@property
@cached_property
def data_as_json(self) -> dict:
"""Decoded base64-encoded data loaded to json"""
if self._json_data is None:
self._json_data = self._json_deserializer(self.data_as_text)
return self._json_data
return self._json_deserializer(self.data_as_text)

def build_data_transformation_response(
self,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from functools import cached_property
from typing import Any, Dict, List

from aws_lambda_powertools.utilities.data_classes.common import DictWrapper
Expand Down Expand Up @@ -84,12 +85,10 @@ def decoded_data(self) -> str:
"""Decodes the data as a str"""
return base64_decode(self.data)

@property
@cached_property
def json_data(self) -> Any:
"""Parses the data as json"""
if self._json_data is None:
self._json_data = self._json_deserializer(self.decoded_data)
return self._json_data
return self._json_deserializer(self.decoded_data)


class RabbitMQEvent(DictWrapper):
Expand Down
7 changes: 3 additions & 4 deletions aws_lambda_powertools/utilities/data_classes/sqs_event.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from functools import cached_property
from typing import Any, Dict, Iterator, Optional, Type, TypeVar

from aws_lambda_powertools.utilities.data_classes import S3Event
Expand Down Expand Up @@ -107,7 +108,7 @@ def body(self) -> str:
"""The message's contents (not URL-encoded)."""
return self["body"]

@property
@cached_property
def json_body(self) -> Any:
"""Deserializes JSON string available in 'body' property
Expand All @@ -132,9 +133,7 @@ def json_body(self) -> Any:
data: list = record.json_body # ["telemetry_values"]
```
"""
if self._json_data is None:
self._json_data = self._json_deserializer(self["body"])
return self._json_data
return self._json_deserializer(self["body"])

@property
def attributes(self) -> SQSRecordAttributes:
Expand Down
Loading

0 comments on commit 95d8eda

Please sign in to comment.