diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 74242e8c9ab..c670ea38274 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -58,7 +58,6 @@ body: attributes: label: AWS Lambda function runtime options: - - "3.7" - "3.8" - "3.9" - "3.10" diff --git a/.github/ISSUE_TEMPLATE/static_typing.yml b/.github/ISSUE_TEMPLATE/static_typing.yml index 29b59ea1461..eb8c7a77387 100644 --- a/.github/ISSUE_TEMPLATE/static_typing.yml +++ b/.github/ISSUE_TEMPLATE/static_typing.yml @@ -25,7 +25,6 @@ body: attributes: label: AWS Lambda function runtime options: - - "3.7" - "3.8" - "3.9" - "3.10" diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 61b48420cfc..3fee4d6b427 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -19,4 +19,4 @@ jobs: - name: 'Checkout Repository' uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: 'Dependency Review' - uses: actions/dependency-review-action@c74b580d73376b7750d3d2a50bfb8adc2c937507 # v3.1.5 + uses: actions/dependency-review-action@4901385134134e04cec5fbe5ddfe3b2c5bd5d976 # v4.0.0 diff --git a/.github/workflows/ossf_scorecard.yml b/.github/workflows/ossf_scorecard.yml index b74a138f692..d9e065bf1e8 100644 --- a/.github/workflows/ossf_scorecard.yml +++ b/.github/workflows/ossf_scorecard.yml @@ -35,7 +35,7 @@ jobs: repo_token: ${{ secrets.SCORECARD_TOKEN }} # read-only fine-grained token to read branch protection settings - name: "Upload results" - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: SARIF file path: results.sarif diff --git a/.github/workflows/publish_v2_layer.yml b/.github/workflows/publish_v2_layer.yml index f067d02becd..f9a5bded5e0 100644 --- a/.github/workflows/publish_v2_layer.yml +++ b/.github/workflows/publish_v2_layer.yml @@ -146,7 +146,7 @@ jobs: - name: zip output run: zip -r cdk.out.zip cdk.out - name: Archive CDK artifacts - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: cdk-layer-artefact path: layer/cdk.out.zip @@ -258,7 +258,7 @@ jobs: artifact_name: ${{ inputs.source_code_artifact_name }} - name: Download CDK layer artifact - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2 with: name: cdk-layer-stack path: cdk-layer-stack/ diff --git a/.github/workflows/quality_check.yml b/.github/workflows/quality_check.yml index 40ccbe99887..fe5616711c6 100644 --- a/.github/workflows/quality_check.yml +++ b/.github/workflows/quality_check.yml @@ -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: @@ -71,7 +71,7 @@ jobs: - name: Complexity baseline run: make complexity-baseline - name: Upload coverage to Codecov - uses: codecov/codecov-action@ab904c41d6ece82784817410c45d8b8c02684457 # 3.1.6 + uses: codecov/codecov-action@e0b68c6749509c5f83f984dd99a76a1c1a231044 # 4.0.1 with: file: ./coverage.xml env_vars: PYTHON diff --git a/.github/workflows/quality_check_pydanticv2.yml b/.github/workflows/quality_check_pydanticv2.yml index d0af2934986..2d84f1154ba 100644 --- a/.github/workflows/quality_check_pydanticv2.yml +++ b/.github/workflows/quality_check_pydanticv2.yml @@ -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: diff --git a/.github/workflows/record_pr.yml b/.github/workflows/record_pr.yml index b74dd4b4ee0..ddfd7c249a3 100644 --- a/.github/workflows/record_pr.yml +++ b/.github/workflows/record_pr.yml @@ -53,7 +53,7 @@ jobs: script: | const script = require('.github/scripts/save_pr_details.js') await script({github, context, core}) - - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: pr path: pr.txt diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 6d4ef78ecc1..473968803b0 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -27,6 +27,6 @@ jobs: permissions: contents: write # create release in draft mode steps: - - uses: release-drafter/release-drafter@09c613e259eb8d4e7c81c2cb00618eb5fc4575a7 # v5.20.1 + - uses: release-drafter/release-drafter@3f0f87098bd6b5c5b9a36d49c41d998ea58f9348 # v5.20.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/reusable_deploy_v2_layer_stack.yml b/.github/workflows/reusable_deploy_v2_layer_stack.yml index d271050fa86..e0441015fe6 100644 --- a/.github/workflows/reusable_deploy_v2_layer_stack.yml +++ b/.github/workflows/reusable_deploy_v2_layer_stack.yml @@ -180,7 +180,7 @@ jobs: - name: install deps run: poetry install - name: Download artifact - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2 with: name: ${{ inputs.artefact-name }} path: layer @@ -197,11 +197,12 @@ jobs: cat cdk-layer-stack/${{ matrix.region }}-layer-version.txt - name: Save Layer ARN artifact if: ${{ inputs.stage == 'PROD' }} - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: cdk-layer-stack path: ./layer/cdk-layer-stack/* # NOTE: upload-artifact does not inherit working-directory setting. if-no-files-found: error retention-days: 1 + overwrite: true - name: CDK Deploy Canary run: npx cdk deploy --app cdk.out --context region=${{ matrix.region }} --parameters DeployStage="${{ inputs.stage }}" --parameters HasARM64Support=${{ matrix.has_arm64_support }} 'CanaryV2Stack' --require-approval never --verbose diff --git a/.github/workflows/reusable_deploy_v2_sar.yml b/.github/workflows/reusable_deploy_v2_sar.yml index c95bc69a006..8fc0480f319 100644 --- a/.github/workflows/reusable_deploy_v2_sar.yml +++ b/.github/workflows/reusable_deploy_v2_sar.yml @@ -115,7 +115,7 @@ jobs: with: node-version: ${{ env.NODE_VERSION }} - name: Download artifact - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2 with: name: ${{ inputs.artefact-name }} - name: Unzip artefact diff --git a/.github/workflows/run-e2e-tests.yml b/.github/workflows/run-e2e-tests.yml index cff41718d87..5780bba255b 100644 --- a/.github/workflows/run-e2e-tests.yml +++ b/.github/workflows/run-e2e-tests.yml @@ -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" diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ea1e02b55a..9bceb7116d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,17 @@ ## Maintenance +* **ci:** drop support for Python 3.7 ([#3638](https://github.com/aws-powertools/powertools-lambda-python/issues/3638)) +* **deps:** bump squidfunk/mkdocs-material from `a4a2029` to `e0d6c67` in /docs ([#3708](https://github.com/aws-powertools/powertools-lambda-python/issues/3708)) +* **deps:** bump release-drafter/release-drafter from 5.25.0 to 6.0.0 ([#3699](https://github.com/aws-powertools/powertools-lambda-python/issues/3699)) +* **deps:** bump actions/dependency-review-action from 3.1.5 to 4.0.0 ([#3646](https://github.com/aws-powertools/powertools-lambda-python/issues/3646)) +* **deps:** bump codecov/codecov-action from 3.1.6 to 4.0.1 ([#3700](https://github.com/aws-powertools/powertools-lambda-python/issues/3700)) +* **deps:** bump actions/download-artifact from 3.0.2 to 4.1.1 ([#3612](https://github.com/aws-powertools/powertools-lambda-python/issues/3612)) +* **deps-dev:** bump the boto-typing group with 7 updates ([#3709](https://github.com/aws-powertools/powertools-lambda-python/issues/3709)) +* **deps-dev:** bump coverage from 7.2.7 to 7.4.1 ([#3713](https://github.com/aws-powertools/powertools-lambda-python/issues/3713)) +* **deps-dev:** bump ruff from 0.1.15 to 0.2.0 ([#3702](https://github.com/aws-powertools/powertools-lambda-python/issues/3702)) * **deps-dev:** bump aws-cdk from 2.125.0 to 2.126.0 ([#3701](https://github.com/aws-powertools/powertools-lambda-python/issues/3701)) +* **deps-dev:** bump httpx from 0.24.1 to 0.26.0 ([#3712](https://github.com/aws-powertools/powertools-lambda-python/issues/3712)) diff --git a/README.md b/README.md index d3f0ec30603..c1ab7abaf29 100644 --- a/README.md +++ b/README.md @@ -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). diff --git a/aws_lambda_powertools/logging/compat.py b/aws_lambda_powertools/logging/compat.py deleted file mode 100644 index ebbefb7af6c..00000000000 --- a/aws_lambda_powertools/logging/compat.py +++ /dev/null @@ -1,51 +0,0 @@ -"""Maintenance: We can drop this upon Py3.7 EOL. It's a backport for "location" key to work.""" -from __future__ import annotations - -import io -import logging -import os -import traceback - - -def findCaller(stack_info=False, stacklevel=2): # pragma: no cover - """ - Find the stack frame of the caller so that we can note the source - file name, line number and function name. - """ - f = logging.currentframe() # noqa: VNE001 - # On some versions of IronPython, currentframe() returns None if - # IronPython isn't run with -X:Frames. - if f is None: - return "(unknown file)", 0, "(unknown function)", None - while stacklevel > 0: - next_f = f.f_back - if next_f is None: - ## We've got options here. - ## If we want to use the last (deepest) frame: - break - ## If we want to mimic the warnings module: - # return ("sys", 1, "(unknown function)", None) # noqa: ERA001 - ## If we want to be pedantic: # noqa: ERA001 - # raise ValueError("call stack is not deep enough") # noqa: ERA001 - f = next_f # noqa: VNE001 - if not _is_internal_frame(f): - stacklevel -= 1 - co = f.f_code - sinfo = None - if stack_info: - with io.StringIO() as sio: - sio.write("Stack (most recent call last):\n") - traceback.print_stack(f, file=sio) - sinfo = sio.getvalue() - if sinfo[-1] == "\n": - sinfo = sinfo[:-1] - return co.co_filename, f.f_lineno, co.co_name, sinfo - - -# The following is based on warnings._is_internal_frame. It makes sure that -# frames of the import mechanism are skipped when logging at module level and -# using a stacklevel value greater than one. -def _is_internal_frame(frame): # pragma: no cover - """Signal whether the frame is a CPython or logging module internal.""" - filename = os.path.normcase(frame.f_code.co_filename) - return filename == logging._srcfile or ("importlib" in filename and "_bootstrap" in filename) diff --git a/aws_lambda_powertools/logging/logger.py b/aws_lambda_powertools/logging/logger.py index 88c903b7cb6..ab159061bff 100644 --- a/aws_lambda_powertools/logging/logger.py +++ b/aws_lambda_powertools/logging/logger.py @@ -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, @@ -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) @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, @@ -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, diff --git a/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py b/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py index e1366a8a725..f5859c5a48d 100644 --- a/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py +++ b/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py @@ -241,8 +241,8 @@ def serialize_metric_set( ], }, # NOTE: Mypy doesn't recognize splats '** syntax' in TypedDict - **dimensions, # type: ignore[misc] # "service": "test_service" - **metadata, # "username": "test" + **dimensions, # "service": "test_service" + **metadata, # type: ignore[typeddict-item] # "username": "test" **metric_names_and_values, # "single_metric": 1.0 } diff --git a/aws_lambda_powertools/shared/types.py b/aws_lambda_powertools/shared/types.py index 100005159e4..d5014c4c467 100644 --- a/aws_lambda_powertools/shared/types.py +++ b/aws_lambda_powertools/shared/types.py @@ -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 @@ -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): diff --git a/aws_lambda_powertools/utilities/data_classes/active_mq_event.py b/aws_lambda_powertools/utilities/data_classes/active_mq_event.py index f5404154ea7..f0839a70442 100644 --- a/aws_lambda_powertools/utilities/data_classes/active_mq_event.py +++ b/aws_lambda_powertools/utilities/data_classes/active_mq_event.py @@ -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 @@ -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: diff --git a/aws_lambda_powertools/utilities/data_classes/code_pipeline_job_event.py b/aws_lambda_powertools/utilities/data_classes/code_pipeline_job_event.py index 1813d6016b5..cc7a75cc05e 100644 --- a/aws_lambda_powertools/utilities/data_classes/code_pipeline_job_event.py +++ b/aws_lambda_powertools/utilities/data_classes/code_pipeline_job_event.py @@ -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 @@ -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): diff --git a/aws_lambda_powertools/utilities/data_classes/common.py b/aws_lambda_powertools/utilities/data_classes/common.py index 0560159ecc5..25fb5a4c170 100644 --- a/aws_lambda_powertools/utilities/data_classes/common.py +++ b/aws_lambda_powertools/utilities/data_classes/common.py @@ -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 @@ -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: @@ -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"] diff --git a/aws_lambda_powertools/utilities/data_classes/kafka_event.py b/aws_lambda_powertools/utilities/data_classes/kafka_event.py index f54f979bace..d3d1425f0f2 100644 --- a/aws_lambda_powertools/utilities/data_classes/kafka_event.py +++ b/aws_lambda_powertools/utilities/data_classes/kafka_event.py @@ -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 @@ -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]]]: diff --git a/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py b/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py index 3e5db8cb9d8..492aac53176 100644 --- a/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py +++ b/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py @@ -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 @@ -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: @@ -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) @@ -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, diff --git a/aws_lambda_powertools/utilities/data_classes/rabbit_mq_event.py b/aws_lambda_powertools/utilities/data_classes/rabbit_mq_event.py index ab792f3b893..0eaae042621 100644 --- a/aws_lambda_powertools/utilities/data_classes/rabbit_mq_event.py +++ b/aws_lambda_powertools/utilities/data_classes/rabbit_mq_event.py @@ -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 @@ -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): diff --git a/aws_lambda_powertools/utilities/data_classes/sqs_event.py b/aws_lambda_powertools/utilities/data_classes/sqs_event.py index ffec9854a2e..4ca1b8f51c9 100644 --- a/aws_lambda_powertools/utilities/data_classes/sqs_event.py +++ b/aws_lambda_powertools/utilities/data_classes/sqs_event.py @@ -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 @@ -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 @@ -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: diff --git a/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py b/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py index f12c53d841a..15144e41d7d 100644 --- a/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py +++ b/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py @@ -1,3 +1,4 @@ +from functools import cached_property from typing import Any, Dict, Optional, overload from aws_lambda_powertools.shared.headers_serializer import ( @@ -18,12 +19,10 @@ def body(self) -> str: """The VPC Lattice body.""" return self["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 def headers(self) -> Dict[str, str]: diff --git a/aws_lambda_powertools/utilities/streaming/compat.py b/aws_lambda_powertools/utilities/streaming/compat.py index 531c7c6e7fa..1b30b3a74f0 100644 --- a/aws_lambda_powertools/utilities/streaming/compat.py +++ b/aws_lambda_powertools/utilities/streaming/compat.py @@ -1,206 +1,4 @@ -""" -Currently, the same as https://github.com/boto/botocore/blob/b9c540905a6c9/botocore/response.py -We created this because the version of StreamingBody included with the Lambda Runtime is too old, and -doesn't support many of the standard IO methods (like readline). +from botocore.response import StreamingBody -As soon as the version of botocore included with the Lambda runtime is equal or greater than 1.29.13, we can drop -this file completely. See https://docs.aws.amazon.com/lambda/latest/dg/lambda-python.html. -""" -import logging -from io import IOBase -from typing import Optional - -import botocore -from botocore import endpoint -from botocore.compat import set_socket_timeout -from botocore.exceptions import ( - IncompleteReadError, - ReadTimeoutError, - ResponseStreamingError, -) -from urllib3.exceptions import ProtocolError as URLLib3ProtocolError -from urllib3.exceptions import ReadTimeoutError as URLLib3ReadTimeoutError - -logger = logging.getLogger(__name__) - -# Splitting the botocore version string into major, minor, and patch versions, -# and performing a conditional check based on the extracted versions. -major, minor, patch = map(int, botocore.__version__.split(".")) - -if major == 1 and (minor < 29 or patch < 13): - - class PowertoolsStreamingBody(IOBase): - """Wrapper class for a HTTP response body. - - This provides a few additional conveniences that do not exist - in the urllib3 model: - * Set the timeout on the socket (i.e read() timeouts) - * Auto validation of content length, if the amount of bytes - we read does not match the content length, an exception - is raised. - """ - - _DEFAULT_CHUNK_SIZE = 1024 - - def __init__(self, raw_stream, content_length): - self._raw_stream = raw_stream - self._content_length = content_length - self._amount_read = 0 - - def __del__(self): - # Extending destructor in order to preserve the underlying raw_stream. - # The ability to add custom cleanup logic introduced in Python3.4+. - # https://www.python.org/dev/peps/pep-0442/ - pass - - def set_socket_timeout(self, timeout): - """Set the timeout seconds on the socket.""" - # The problem we're trying to solve is to prevent .read() calls from - # hanging. This can happen in rare cases. What we'd like to ideally - # do is set a timeout on the .read() call so that callers can retry - # the request. - # Unfortunately, this isn't currently possible in requests. - # See: https://github.com/kennethreitz/requests/issues/1803 - # So what we're going to do is reach into the guts of the stream and - # grab the socket object, which we can set the timeout on. We're - # putting in a check here so in case this interface goes away, we'll - # know. - try: - set_socket_timeout(self._raw_stream, timeout) - except AttributeError: - logger.error( - "Cannot access the socket object of " - "a streaming response. It's possible " - "the interface has changed.", - exc_info=True, - ) - raise - - def readable(self): - try: - return self._raw_stream.readable() - except AttributeError: - return False - - def read(self, amt=None): - """Read at most amt bytes from the stream. - If the amt argument is omitted, read all data. - """ - try: - chunk = self._raw_stream.read(amt) - except URLLib3ReadTimeoutError as e: - raise ReadTimeoutError(endpoint_url=e.url, error=e) - except URLLib3ProtocolError as e: - raise ResponseStreamingError(error=e) - self._amount_read += len(chunk) - if amt is None or (not chunk and amt > 0): - # If the server sends empty contents or - # we ask to read all of the contents, then we know - # we need to verify the content length. - self._verify_content_length() - return chunk - - def readlines(self, hint: Optional[int] = -1): - return self._raw_stream.readlines(hint) - - def __iter__(self): - """Return an iterator to yield 1k chunks from the raw stream.""" - return self.iter_chunks(self._DEFAULT_CHUNK_SIZE) - - def __next__(self): - """Return the next 1k chunk from the raw stream.""" - current_chunk = self.read(self._DEFAULT_CHUNK_SIZE) - if current_chunk: - return current_chunk - raise StopIteration() - - def __enter__(self): - return self._raw_stream - - def __exit__(self, *args): - self._raw_stream.close() - - next = __next__ # noqa: A003, VNE003 - - def iter_lines(self, chunk_size=_DEFAULT_CHUNK_SIZE, keepends=False): - """Return an iterator to yield lines from the raw stream. - This is achieved by reading chunk of bytes (of size chunk_size) at a - time from the raw stream, and then yielding lines from there. - """ - pending = b"" - for chunk in self.iter_chunks(chunk_size): - lines = (pending + chunk).splitlines(True) - for line in lines[:-1]: - yield line.splitlines(keepends)[0] - pending = lines[-1] - if pending: - yield pending.splitlines(keepends)[0] - - def iter_chunks(self, chunk_size=_DEFAULT_CHUNK_SIZE): - """Return an iterator to yield chunks of chunk_size bytes from the raw - stream. - """ - while True: - current_chunk = self.read(chunk_size) - if current_chunk == b"": - break - yield current_chunk - - def _verify_content_length(self): - # See: https://github.com/kennethreitz/requests/issues/1855 - # Basically, our http library doesn't do this for us, so we have - # to do this ourself. - if self._content_length is not None and self._amount_read != int(self._content_length): - raise IncompleteReadError( - actual_bytes=self._amount_read, - expected_bytes=int(self._content_length), - ) - - def tell(self): - return self._raw_stream.tell() - - def close(self): - """Close the underlying http response stream.""" - self._raw_stream.close() - - def convert_to_response_dict(http_response, operation_model): - """Convert an HTTP response object to a request dict. - - This converts the requests library's HTTP response object to - a dictionary. - - :type http_response: botocore.vendored.requests.model.Response - :param http_response: The HTTP response from an AWS service request. - - :rtype: dict - :return: A response dictionary which will contain the following keys: - * headers (dict) - * status_code (int) - * body (string or file-like object) - - """ - response_dict = { - "headers": http_response.headers, - "status_code": http_response.status_code, - "context": { - "operation_name": operation_model.name, - }, - } - if response_dict["status_code"] >= 300: - response_dict["body"] = http_response.content - elif operation_model.has_event_stream_output: - response_dict["body"] = http_response.raw - elif operation_model.has_streaming_output: - length = response_dict["headers"].get("content-length") - response_dict["body"] = PowertoolsStreamingBody(http_response.raw, length) - else: - response_dict["body"] = http_response.content - return response_dict - - # monkey patch boto3 - endpoint.convert_to_response_dict = convert_to_response_dict -else: - from botocore.response import StreamingBody - - # Expose PowertoolsStreamingBody as StreamingBody - vars()["PowertoolsStreamingBody"] = StreamingBody +# aliasing as 3.7 is no longer supported but unsure if anyone took a dependency on it (hyrum's law) +PowertoolsStreamingBody = StreamingBody diff --git a/docs/Dockerfile b/docs/Dockerfile index 82bf5a39aeb..640182ff441 100644 --- a/docs/Dockerfile +++ b/docs/Dockerfile @@ -1,5 +1,5 @@ # v9.1.18 -FROM squidfunk/mkdocs-material@sha256:a4a2029fdf524f0c727852e492cd2bbae30cc9471959da60d7dc46bf565a521b +FROM squidfunk/mkdocs-material@sha256:e0d6c671fa3d5cf332043a5231c6f0cd68f48607e9edf710c2f3a57a74dbdc93 # pip-compile --generate-hashes --output-file=requirements.txt requirements.in COPY requirements.txt /tmp/ RUN pip install --require-hashes -r /tmp/requirements.txt diff --git a/docs/core/event_handler/appsync.md b/docs/core/event_handler/appsync.md index 789bf788004..fcadc2a1f27 100644 --- a/docs/core/event_handler/appsync.md +++ b/docs/core/event_handler/appsync.md @@ -61,7 +61,7 @@ Here's an example with two separate functions to resolve `getTodo` and `listTodo === "getting_started_graphql_api_resolver.py" - ```python hl_lines="14 21 31 33-34 43 45 53 55 66" + ```python hl_lines="7 15 25 27 28 37 39 47 49 60" --8<-- "examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py" ``` @@ -123,7 +123,7 @@ You can nest `app.resolver()` decorator multiple times when resolving fields wit === "nested_mappings.py" - ```python hl_lines="11 17 27-28 28 30 37" + ```python hl_lines="4 11 21 22 24 31" --8<-- "examples/event_handler_graphql/src/nested_mappings.py" ``` @@ -137,7 +137,7 @@ You can nest `app.resolver()` decorator multiple times when resolving fields wit For Lambda Python3.8+ runtime, this utility supports async functions when you use in conjunction with `asyncio.run`. -```python hl_lines="14 21 31-32 41 43" title="Resolving GraphQL resolvers async" +```python hl_lines="6 15 25 26 35 37" title="Resolving GraphQL resolvers async" --8<-- "examples/event_handler_graphql/src/async_resolvers.py" ``` @@ -162,13 +162,13 @@ Use the following code for `merchantInfo` and `searchMerchant` functions respect === "graphql_transformer_merchant_info.py" - ```python hl_lines="11 13 29-30 34-35 43" + ```python hl_lines="4 7 23 24 29 30 37" --8<-- "examples/event_handler_graphql/src/graphql_transformer_merchant_info.py" ``` === "graphql_transformer_search_merchant.py" - ```python hl_lines="11 13 28-29 43 49" + ```python hl_lines="4 7 22 23 37 43" --8<-- "examples/event_handler_graphql/src/graphql_transformer_search_merchant.py" ``` @@ -196,7 +196,7 @@ You can subclass [AppSyncResolverEvent](../../utilities/data_classes.md#appsync- === "custom_models.py.py" - ```python hl_lines="11 14 32-34 37-38 45 52" + ```python hl_lines="4 8-10 26-28 31 32 39 46" --8<-- "examples/event_handler_graphql/src/custom_models.py" ``` @@ -225,7 +225,7 @@ Let's assume you have `split_operation.py` as your Lambda function entrypoint an We import **Router** instead of **AppSyncResolver**; syntax wise is exactly the same. - ```python hl_lines="11 15 25-26" + ```python hl_lines="4 9 19 20" --8<-- "examples/event_handler_graphql/src/split_operation_module.py" ``` @@ -255,7 +255,7 @@ You can use `append_context` when you want to share data between your App and Ro === "split_route_append_context_module.py" - ```python hl_lines="29" + ```python hl_lines="23" --8<-- "examples/event_handler_graphql/src/split_operation_append_context_module.py" ``` @@ -269,13 +269,13 @@ Here's an example of how you can test your synchronous resolvers: === "assert_graphql_response.py" - ```python hl_lines="6 26 29" + ```python hl_lines="8 28 31" --8<-- "examples/event_handler_graphql/src/assert_graphql_response.py" ``` === "assert_graphql_response_module.py" - ```python hl_lines="17" + ```python hl_lines="11" --8<-- "examples/event_handler_graphql/src/assert_graphql_response_module.py" ``` @@ -298,7 +298,7 @@ And an example for testing asynchronous resolvers. Note that this requires the ` === "assert_async_graphql_response_module.py" - ```python hl_lines="21" + ```python hl_lines="15" --8<-- "examples/event_handler_graphql/src/assert_async_graphql_response_module.py" ``` diff --git a/docs/roadmap.md b/docs/roadmap.md index e42fae21c97..766733c754c 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -120,7 +120,7 @@ We want to investigate security and scaling requirements for these special regio ### V3 -With Python 3.7 reaching [end-of-life in AWS Lambda by the end of the year](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html), we want to plan some breaking changes. As always, we plan on having ample notice, a detailed upgrade guide, and keep breaking changes to a minimum to ease transition (e.g., it took ~7 months from v2 to surpass v1 downloads). +We are in the process of planning the roadmap for v3. As always, our approach includes providing sufficient advance notice, a comprehensive upgrade guide, and minimizing breaking changes to facilitate a smooth transition (e.g., it took ~7 months from v2 to surpass v1 downloads). For example, these are on our mind but not settled yet until we have a public tracker to discuss what these means in detail. @@ -128,7 +128,6 @@ For example, these are on our mind but not settled yet until we have a public tr - **Parser**: Deserialize Amazon DynamoDB data types automatically (like Event Source Data Classes) - **Parameters**: Increase default `max_age` for `get_secret` - **Event Source Data Classes**: Return sane defaults for any property that has `Optional[]` returns -- **Python 3.7 EOL**: Update PyPi and Layers to only support 3.8 - **Upgrade tool**: Consider building a CST (Concrete Syntax Tree) tool to ease certain upgrade actions like `pyupgrade` and `django-upgrade` - **Batch**: Stop at first error for Amazon DynamoDB Streams and Amazon Kinesis Data Streams (e.g., `stop_on_failure=True`) diff --git a/docs/upgrade.md b/docs/upgrade.md index d9602da1a53..11d8cdbe83a 100644 --- a/docs/upgrade.md +++ b/docs/upgrade.md @@ -32,7 +32,7 @@ We've made minimal breaking changes to make your transition to v2 as smooth as p Before you start, we suggest making a copy of your current working project or create a new branch with git. -1. **Upgrade** Python to at least v3.7 +1. **Upgrade** Python to at least v3.8 2. **Ensure** you have the latest version via [Lambda Layer or PyPi](index.md#install){target="_blank"}. 3. **Review** the following sections to confirm whether they affect your code diff --git a/docs/utilities/idempotency.md b/docs/utilities/idempotency.md index bc355580935..17848a7828b 100644 --- a/docs/utilities/idempotency.md +++ b/docs/utilities/idempotency.md @@ -143,7 +143,7 @@ Similar to [idempotent decorator](#idempotent-decorator), you can use `idempoten When using `idempotent_function`, you must tell us which keyword parameter in your function signature has the data we should use via **`data_keyword_argument`**. -!!! tip "We support JSON serializable data, [Python Dataclasses](https://docs.python.org/3.7/library/dataclasses.html){target="_blank" rel="nofollow"}, [Parser/Pydantic Models](parser.md){target="_blank"}, and our [Event Source Data Classes](./data_classes.md){target="_blank"}." +!!! tip "We support JSON serializable data, [Python Dataclasses](https://docs.python.org/3.12/library/dataclasses.html){target="_blank" rel="nofollow"}, [Parser/Pydantic Models](parser.md){target="_blank"}, and our [Event Source Data Classes](./data_classes.md){target="_blank"}." ???+ warning "Limitation" Make sure to call your decorated function using keyword arguments. diff --git a/docs/we_made_this.md b/docs/we_made_this.md index 74d68e29227..d57a0b7325c 100644 --- a/docs/we_made_this.md +++ b/docs/we_made_this.md @@ -104,6 +104,14 @@ This blog post showcases how to use AWS CDK and Powertools for AWS Lambda, along [Creating a serverless API using Powertools for AWS Lambda and CDK](https://how.wtf/creating-a-serverless-api-using-aws-lambda-powertools-and-cdk.html){target="_blank" rel="nofollow"} +### Boost App Engagement with AWS CloudWatch Metrics & Powertools for AWS + +This article will guide you through personalizing observability by integrating CloudWatch metrics with Powertools for AWS Lambda into mobile push notifications, a strategy that significantly enhances mobile app engagement + +> **Author: [Nathan Hanks](https://www.linkedin.com/in/nathan-hanks-25151815/){target="_blank" rel="nofollow"}** :material-linkedin: + +[Creating a serverless API using Powertools for AWS Lambda and CDK](https://www.ranthebuilder.cloud/post/boost-app-engagement-with-aws-cloudwatch-metrics-powertools-for-aws){target="_blank" rel="nofollow"} + ## Videos #### Building a resilient input handling with Parser diff --git a/examples/event_handler_graphql/src/assert_async_graphql_response_module.py b/examples/event_handler_graphql/src/assert_async_graphql_response_module.py index 8ef072a02f7..371eeaa23f8 100644 --- a/examples/event_handler_graphql/src/assert_async_graphql_response_module.py +++ b/examples/event_handler_graphql/src/assert_async_graphql_response_module.py @@ -1,10 +1,3 @@ -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - import asyncio from typing import List @@ -13,6 +6,7 @@ from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import AppSyncResolver from aws_lambda_powertools.logging import correlation_paths +from aws_lambda_powertools.shared.types import TypedDict from aws_lambda_powertools.tracing import aiohttp_trace_config from aws_lambda_powertools.utilities.typing import LambdaContext diff --git a/examples/event_handler_graphql/src/assert_graphql_response_module.py b/examples/event_handler_graphql/src/assert_graphql_response_module.py index c7869a587fc..a7cb58c1d98 100644 --- a/examples/event_handler_graphql/src/assert_graphql_response_module.py +++ b/examples/event_handler_graphql/src/assert_graphql_response_module.py @@ -1,15 +1,9 @@ -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - from typing import List from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import AppSyncResolver from aws_lambda_powertools.logging import correlation_paths +from aws_lambda_powertools.shared.types import TypedDict from aws_lambda_powertools.utilities.typing import LambdaContext tracer = Tracer() diff --git a/examples/event_handler_graphql/src/async_resolvers.py b/examples/event_handler_graphql/src/async_resolvers.py index 072f42dbba9..08ecbcba85b 100644 --- a/examples/event_handler_graphql/src/async_resolvers.py +++ b/examples/event_handler_graphql/src/async_resolvers.py @@ -1,11 +1,4 @@ import asyncio -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - from typing import List import aiohttp @@ -13,6 +6,7 @@ from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import AppSyncResolver from aws_lambda_powertools.logging import correlation_paths +from aws_lambda_powertools.shared.types import TypedDict from aws_lambda_powertools.tracing import aiohttp_trace_config from aws_lambda_powertools.utilities.typing import LambdaContext diff --git a/examples/event_handler_graphql/src/custom_models.py b/examples/event_handler_graphql/src/custom_models.py index 6d82e1ba9be..ae2f0180e15 100644 --- a/examples/event_handler_graphql/src/custom_models.py +++ b/examples/event_handler_graphql/src/custom_models.py @@ -1,15 +1,9 @@ -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - from typing import List from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import AppSyncResolver from aws_lambda_powertools.logging import correlation_paths +from aws_lambda_powertools.shared.types import TypedDict from aws_lambda_powertools.utilities.data_classes.appsync import scalar_types_utils from aws_lambda_powertools.utilities.data_classes.appsync_resolver_event import ( AppSyncResolverEvent, diff --git a/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py b/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py index 9edd8c68dad..e960a357d17 100644 --- a/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py +++ b/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py @@ -1,10 +1,3 @@ -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - from typing import List import requests @@ -13,6 +6,7 @@ from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import AppSyncResolver from aws_lambda_powertools.logging import correlation_paths +from aws_lambda_powertools.shared.types import TypedDict from aws_lambda_powertools.utilities.data_classes.appsync import scalar_types_utils from aws_lambda_powertools.utilities.typing import LambdaContext diff --git a/examples/event_handler_graphql/src/graphql_transformer_merchant_info.py b/examples/event_handler_graphql/src/graphql_transformer_merchant_info.py index 55f963bb8d5..017528e3481 100644 --- a/examples/event_handler_graphql/src/graphql_transformer_merchant_info.py +++ b/examples/event_handler_graphql/src/graphql_transformer_merchant_info.py @@ -1,15 +1,9 @@ -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - from typing import List from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import AppSyncResolver from aws_lambda_powertools.logging import correlation_paths +from aws_lambda_powertools.shared.types import TypedDict from aws_lambda_powertools.utilities.data_classes.appsync import scalar_types_utils from aws_lambda_powertools.utilities.typing import LambdaContext diff --git a/examples/event_handler_graphql/src/graphql_transformer_search_merchant.py b/examples/event_handler_graphql/src/graphql_transformer_search_merchant.py index 1dd52945f93..9b685a280dd 100644 --- a/examples/event_handler_graphql/src/graphql_transformer_search_merchant.py +++ b/examples/event_handler_graphql/src/graphql_transformer_search_merchant.py @@ -1,15 +1,9 @@ -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - from typing import List from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import AppSyncResolver from aws_lambda_powertools.logging import correlation_paths +from aws_lambda_powertools.shared.types import TypedDict from aws_lambda_powertools.utilities.data_classes.appsync import scalar_types_utils from aws_lambda_powertools.utilities.typing import LambdaContext diff --git a/examples/event_handler_graphql/src/nested_mappings.py b/examples/event_handler_graphql/src/nested_mappings.py index c7869a587fc..a7cb58c1d98 100644 --- a/examples/event_handler_graphql/src/nested_mappings.py +++ b/examples/event_handler_graphql/src/nested_mappings.py @@ -1,15 +1,9 @@ -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - from typing import List from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import AppSyncResolver from aws_lambda_powertools.logging import correlation_paths +from aws_lambda_powertools.shared.types import TypedDict from aws_lambda_powertools.utilities.typing import LambdaContext tracer = Tracer() diff --git a/examples/event_handler_graphql/src/split_operation_append_context_module.py b/examples/event_handler_graphql/src/split_operation_append_context_module.py index e30e345c313..15ed7af1b9e 100644 --- a/examples/event_handler_graphql/src/split_operation_append_context_module.py +++ b/examples/event_handler_graphql/src/split_operation_append_context_module.py @@ -1,14 +1,8 @@ -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - from typing import List from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler.appsync import Router +from aws_lambda_powertools.shared.types import TypedDict tracer = Tracer() logger = Logger() diff --git a/examples/event_handler_graphql/src/split_operation_module.py b/examples/event_handler_graphql/src/split_operation_module.py index 12569bc23bc..e4c7f978b73 100644 --- a/examples/event_handler_graphql/src/split_operation_module.py +++ b/examples/event_handler_graphql/src/split_operation_module.py @@ -1,14 +1,8 @@ -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - from typing import List from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler.appsync import Router +from aws_lambda_powertools.shared.types import TypedDict tracer = Tracer() logger = Logger() diff --git a/examples/idempotency/src/working_with_idempotent_function_custom_output_serializer.py b/examples/idempotency/src/working_with_idempotent_function_custom_output_serializer.py index e32d5da868e..a62961fa5f3 100644 --- a/examples/idempotency/src/working_with_idempotent_function_custom_output_serializer.py +++ b/examples/idempotency/src/working_with_idempotent_function_custom_output_serializer.py @@ -30,7 +30,7 @@ def __init__(self, order_id: int): def order_to_dict(x: Type[OrderOutput]) -> Dict: # (1)! - return x.__dict__ + return dict(x.__dict__) def dict_to_order(x: Dict) -> OrderOutput: # (2)! diff --git a/layer/sar/template.txt b/layer/sar/template.txt index fc6ed8892a4..d813a6a77d7 100644 --- a/layer/sar/template.txt +++ b/layer/sar/template.txt @@ -14,7 +14,7 @@ Metadata: SourceCodeUrl: https://github.com/aws-powertools/powertools-lambda-python Transform: AWS::Serverless-2016-10-31 -Description: AWS Lambda Layer for aws-lambda-powertools with python 3.12, 3.11, 3.10, 3.9, 3.8 or 3.7 +Description: AWS Lambda Layer for aws-lambda-powertools with python 3.12, 3.11, 3.10, 3.9 or 3.8 Resources: LambdaLayer: @@ -29,7 +29,6 @@ Resources: - python3.10 - python3.9 - python3.8 - - python3.7 LicenseInfo: 'Available under the Apache-2.0 license.' RetentionPolicy: Retain diff --git a/poetry.lock b/poetry.lock index 0469f6df30f..b62788f35fa 100644 --- a/poetry.lock +++ b/poetry.lock @@ -15,7 +15,6 @@ files = [ exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"] @@ -33,9 +32,6 @@ files = [ {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, ] -[package.dependencies] -typing-extensions = {version = ">=3.6.5", markers = "python_version < \"3.8\""} - [[package]] name = "attrs" version = "23.2.0" @@ -47,9 +43,6 @@ files = [ {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, ] -[package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} - [package.extras] cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] dev = ["attrs[tests]", "pre-commit"] @@ -60,17 +53,17 @@ tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "p [[package]] name = "aws-cdk-asset-awscli-v1" -version = "2.2.201" +version = "2.2.202" description = "A library that contains the AWS CLI for use in Lambda Layers" optional = false -python-versions = "~=3.7" +python-versions = "~=3.8" files = [ - {file = "aws-cdk.asset-awscli-v1-2.2.201.tar.gz", hash = "sha256:88d1c269fd5cf8c9f6e0464ed22e2d4f269dfd5b36b8c4d37687bdba9c269839"}, - {file = "aws_cdk.asset_awscli_v1-2.2.201-py3-none-any.whl", hash = "sha256:56fe2ef91d3c8d33559aa32d2130e5f35f23af1fb82f06648ebbc82ffe0a5879"}, + {file = "aws-cdk.asset-awscli-v1-2.2.202.tar.gz", hash = "sha256:3ef87d6530736b3a7b0f777fe3b4297994dd40c3ce9306d95f80f48fb18036e8"}, + {file = "aws_cdk.asset_awscli_v1-2.2.202-py3-none-any.whl", hash = "sha256:96205ea2e5e132ec52fabfff37ea25b9b859498f167d05b32564c949822cd331"}, ] [package.dependencies] -jsii = ">=1.91.0,<2.0.0" +jsii = ">=1.93.0,<2.0.0" publication = ">=0.0.3" typeguard = ">=2.13.3,<2.14.0" @@ -164,21 +157,21 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-lib" -version = "2.111.0" +version = "2.126.0" description = "Version 2 of the AWS Cloud Development Kit library" optional = false -python-versions = "~=3.7" +python-versions = "~=3.8" files = [ - {file = "aws-cdk-lib-2.111.0.tar.gz", hash = "sha256:60a0adaddad146ca682ded4762cb2665b11a095f2d9c2ad84a33ff8f473da161"}, - {file = "aws_cdk_lib-2.111.0-py3-none-any.whl", hash = "sha256:f73174509eb89528a4bcbd50b40dd228120c8bced8089031e72148031ee605a3"}, + {file = "aws-cdk-lib-2.126.0.tar.gz", hash = "sha256:291f9a15fb45f1461644ffa2ff360c8c2ed2797ac29082655252de291fa04333"}, + {file = "aws_cdk_lib-2.126.0-py3-none-any.whl", hash = "sha256:8e00c0a3bfe8f5c20d305d149df251b8fbf292aa7e74df0765ba47fdbbec82d6"}, ] [package.dependencies] -"aws-cdk.asset-awscli-v1" = ">=2.2.201,<3.0.0" +"aws-cdk.asset-awscli-v1" = ">=2.2.202,<3.0.0" "aws-cdk.asset-kubectl-v20" = ">=2.1.2,<3.0.0" "aws-cdk.asset-node-proxy-agent-v6" = ">=2.0.1,<3.0.0" constructs = ">=10.0.0,<11.0.0" -jsii = ">=1.91.0,<2.0.0" +jsii = ">=1.94.0,<2.0.0" publication = ">=0.0.3" typeguard = ">=2.13.3,<2.14.0" @@ -215,23 +208,23 @@ requests = ">=0.14.0" [[package]] name = "aws-sam-translator" -version = "1.82.0" +version = "1.84.0" description = "AWS SAM Translator is a library that transform SAM templates into AWS CloudFormation templates" optional = false -python-versions = ">=3.7, <=4.0, !=4.0" +python-versions = ">=3.8, <=4.0, !=4.0" files = [ - {file = "aws-sam-translator-1.82.0.tar.gz", hash = "sha256:f78e58194461635aef6255d04e82a9b690e331ca9fd669d1401bf7f9a93ae49f"}, - {file = "aws_sam_translator-1.82.0-py3-none-any.whl", hash = "sha256:29ba61f2a70b2b1cf0c76b92b78a23c7cdd19ea1b0a5992753180b56d040d20b"}, + {file = "aws-sam-translator-1.84.0.tar.gz", hash = "sha256:dbfd5669b5ef4bd7bc7af4775eec2ce4db61a2c2a17d721e67b51cf6a6dd63f9"}, + {file = "aws_sam_translator-1.84.0-py3-none-any.whl", hash = "sha256:a24f43e80095c79258a1f1c7a0b8169f55daf0b2bc237d5b9010b02ba86fa3bb"}, ] [package.dependencies] boto3 = ">=1.19.5,<2.dev0" jsonschema = ">=3.2,<5" pydantic = ">=1.8,<3" -typing-extensions = ">=4.4,<5" +typing-extensions = ">=4.4" [package.extras] -dev = ["black (==23.3.0)", "boto3 (>=1.23,<2)", "boto3-stubs[appconfig,serverlessrepo] (>=1.19.5,<2.dev0)", "coverage (>=5.3,<8)", "dateparser (>=1.1,<2.0)", "importlib-metadata", "mypy (>=1.3.0,<1.4.0)", "parameterized (>=0.7,<1.0)", "pytest (>=6.2,<8)", "pytest-cov (>=2.10,<5)", "pytest-env (>=0.6,<1)", "pytest-rerunfailures (>=9.1,<12)", "pytest-xdist (>=2.5,<4)", "pyyaml (>=6.0,<7.0)", "requests (>=2.28,<3.0)", "ruamel.yaml (==0.17.21)", "ruff (==0.0.284)", "tenacity (>=8.0,<9.0)", "types-PyYAML (>=6.0,<7.0)", "types-jsonschema (>=3.2,<4.0)"] +dev = ["black (==23.10.1)", "boto3 (>=1.23,<2)", "boto3-stubs[appconfig,serverlessrepo] (>=1.19.5,<2.dev0)", "coverage (>=5.3,<8)", "dateparser (>=1.1,<2.0)", "mypy (>=1.3.0,<1.4.0)", "parameterized (>=0.7,<1.0)", "pytest (>=6.2,<8)", "pytest-cov (>=2.10,<5)", "pytest-env (>=0.6,<1)", "pytest-rerunfailures (>=9.1,<12)", "pytest-xdist (>=2.5,<4)", "pyyaml (>=6.0,<7.0)", "requests (>=2.28,<3.0)", "ruamel.yaml (==0.17.21)", "ruff (>=0.1.0,<0.2.0)", "tenacity (>=8.0,<9.0)", "types-PyYAML (>=6.0,<7.0)", "types-jsonschema (>=3.2,<4.0)"] [[package]] name = "aws-xray-sdk" @@ -329,7 +322,6 @@ packaging = ">=22.0" pathspec = ">=0.9.0" platformdirs = ">=2" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""} typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} [package.extras] @@ -379,17 +371,6 @@ urllib3 = [ [package.extras] crt = ["awscrt (==0.19.17)"] -[[package]] -name = "bytecode" -version = "0.13.0" -description = "Python module to generate and modify bytecode" -optional = false -python-versions = ">=3.6" -files = [ - {file = "bytecode-0.13.0-py3-none-any.whl", hash = "sha256:e69f92e7d27f99d5d7d76e6a824bd3d9ff857c72b59927aaf87e1a620f67fe50"}, - {file = "bytecode-0.13.0.tar.gz", hash = "sha256:6af3c2f0a31ce05dce41f7eea5cc380e33f5e8fbb7dcee3b52467a00acd52fcd"}, -] - [[package]] name = "bytecode" version = "0.15.1" @@ -518,17 +499,17 @@ pycparser = "*" [[package]] name = "cfn-lint" -version = "0.83.8" +version = "0.85.0" description = "Checks CloudFormation templates for practices and behaviour that could potentially be improved" optional = false -python-versions = ">=3.7, <=4.0, !=4.0" +python-versions = ">=3.8, <=4.0, !=4.0" files = [ - {file = "cfn-lint-0.83.8.tar.gz", hash = "sha256:fbbe31925d78cb9373b160d944ba30cafc085dcd256a3c30139004ef96482154"}, - {file = "cfn_lint-0.83.8-py3-none-any.whl", hash = "sha256:e53b81095e21f0be76de9dc303ddc0290a5eb1ef78173cf3cbc1b6cce9b2dd22"}, + {file = "cfn-lint-0.85.0.tar.gz", hash = "sha256:64d6e8d85cdc573b61add78f9ff95a142a1834edb4793d1291551f6d953f73fe"}, + {file = "cfn_lint-0.85.0-py3-none-any.whl", hash = "sha256:e4849e1779bd1a9f4543617372708a20519b6d7cad5f980e20c6deaa227361a2"}, ] [package.dependencies] -aws-sam-translator = ">=1.82.0" +aws-sam-translator = ">=1.83.0" jschema-to-python = ">=1.2.3,<1.3.0" jsonpatch = "*" jsonschema = ">=3.0,<5" @@ -662,7 +643,6 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} [[package]] name = "colorama" @@ -693,71 +673,63 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "coverage" -version = "7.2.7" +version = "7.4.1" description = "Code coverage measurement for Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "coverage-7.2.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8"}, - {file = "coverage-7.2.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495"}, - {file = "coverage-7.2.7-cp310-cp310-win32.whl", hash = "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818"}, - {file = "coverage-7.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850"}, - {file = "coverage-7.2.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f"}, - {file = "coverage-7.2.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a"}, - {file = "coverage-7.2.7-cp311-cp311-win32.whl", hash = "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a"}, - {file = "coverage-7.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562"}, - {file = "coverage-7.2.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d"}, - {file = "coverage-7.2.7-cp312-cp312-win32.whl", hash = "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511"}, - {file = "coverage-7.2.7-cp312-cp312-win_amd64.whl", hash = "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3"}, - {file = "coverage-7.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02"}, - {file = "coverage-7.2.7-cp37-cp37m-win32.whl", hash = "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f"}, - {file = "coverage-7.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0"}, - {file = "coverage-7.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5"}, - {file = "coverage-7.2.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f"}, - {file = "coverage-7.2.7-cp38-cp38-win32.whl", hash = "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e"}, - {file = "coverage-7.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c"}, - {file = "coverage-7.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9"}, - {file = "coverage-7.2.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2"}, - {file = "coverage-7.2.7-cp39-cp39-win32.whl", hash = "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb"}, - {file = "coverage-7.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27"}, - {file = "coverage-7.2.7-pp37.pp38.pp39-none-any.whl", hash = "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d"}, - {file = "coverage-7.2.7.tar.gz", hash = "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59"}, + {file = "coverage-7.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:077d366e724f24fc02dbfe9d946534357fda71af9764ff99d73c3c596001bbd7"}, + {file = "coverage-7.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0193657651f5399d433c92f8ae264aff31fc1d066deee4b831549526433f3f61"}, + {file = "coverage-7.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d17bbc946f52ca67adf72a5ee783cd7cd3477f8f8796f59b4974a9b59cacc9ee"}, + {file = "coverage-7.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3277f5fa7483c927fe3a7b017b39351610265308f5267ac6d4c2b64cc1d8d25"}, + {file = "coverage-7.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dceb61d40cbfcf45f51e59933c784a50846dc03211054bd76b421a713dcdf19"}, + {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6008adeca04a445ea6ef31b2cbaf1d01d02986047606f7da266629afee982630"}, + {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c61f66d93d712f6e03369b6a7769233bfda880b12f417eefdd4f16d1deb2fc4c"}, + {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b9bb62fac84d5f2ff523304e59e5c439955fb3b7f44e3d7b2085184db74d733b"}, + {file = "coverage-7.4.1-cp310-cp310-win32.whl", hash = "sha256:f86f368e1c7ce897bf2457b9eb61169a44e2ef797099fb5728482b8d69f3f016"}, + {file = "coverage-7.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:869b5046d41abfea3e381dd143407b0d29b8282a904a19cb908fa24d090cc018"}, + {file = "coverage-7.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b8ffb498a83d7e0305968289441914154fb0ef5d8b3157df02a90c6695978295"}, + {file = "coverage-7.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3cacfaefe6089d477264001f90f55b7881ba615953414999c46cc9713ff93c8c"}, + {file = "coverage-7.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d6850e6e36e332d5511a48a251790ddc545e16e8beaf046c03985c69ccb2676"}, + {file = "coverage-7.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18e961aa13b6d47f758cc5879383d27b5b3f3dcd9ce8cdbfdc2571fe86feb4dd"}, + {file = "coverage-7.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfd1e1b9f0898817babf840b77ce9fe655ecbe8b1b327983df485b30df8cc011"}, + {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6b00e21f86598b6330f0019b40fb397e705135040dbedc2ca9a93c7441178e74"}, + {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:536d609c6963c50055bab766d9951b6c394759190d03311f3e9fcf194ca909e1"}, + {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7ac8f8eb153724f84885a1374999b7e45734bf93a87d8df1e7ce2146860edef6"}, + {file = "coverage-7.4.1-cp311-cp311-win32.whl", hash = "sha256:f3771b23bb3675a06f5d885c3630b1d01ea6cac9e84a01aaf5508706dba546c5"}, + {file = "coverage-7.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:9d2f9d4cc2a53b38cabc2d6d80f7f9b7e3da26b2f53d48f05876fef7956b6968"}, + {file = "coverage-7.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f68ef3660677e6624c8cace943e4765545f8191313a07288a53d3da188bd8581"}, + {file = "coverage-7.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:23b27b8a698e749b61809fb637eb98ebf0e505710ec46a8aa6f1be7dc0dc43a6"}, + {file = "coverage-7.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e3424c554391dc9ef4a92ad28665756566a28fecf47308f91841f6c49288e66"}, + {file = "coverage-7.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e0860a348bf7004c812c8368d1fc7f77fe8e4c095d661a579196a9533778e156"}, + {file = "coverage-7.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe558371c1bdf3b8fa03e097c523fb9645b8730399c14fe7721ee9c9e2a545d3"}, + {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3468cc8720402af37b6c6e7e2a9cdb9f6c16c728638a2ebc768ba1ef6f26c3a1"}, + {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:02f2edb575d62172aa28fe00efe821ae31f25dc3d589055b3fb64d51e52e4ab1"}, + {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ca6e61dc52f601d1d224526360cdeab0d0712ec104a2ce6cc5ccef6ed9a233bc"}, + {file = "coverage-7.4.1-cp312-cp312-win32.whl", hash = "sha256:ca7b26a5e456a843b9b6683eada193fc1f65c761b3a473941efe5a291f604c74"}, + {file = "coverage-7.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:85ccc5fa54c2ed64bd91ed3b4a627b9cce04646a659512a051fa82a92c04a448"}, + {file = "coverage-7.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8bdb0285a0202888d19ec6b6d23d5990410decb932b709f2b0dfe216d031d218"}, + {file = "coverage-7.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:918440dea04521f499721c039863ef95433314b1db00ff826a02580c1f503e45"}, + {file = "coverage-7.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:379d4c7abad5afbe9d88cc31ea8ca262296480a86af945b08214eb1a556a3e4d"}, + {file = "coverage-7.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b094116f0b6155e36a304ff912f89bbb5067157aff5f94060ff20bbabdc8da06"}, + {file = "coverage-7.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2f5968608b1fe2a1d00d01ad1017ee27efd99b3437e08b83ded9b7af3f6f766"}, + {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:10e88e7f41e6197ea0429ae18f21ff521d4f4490aa33048f6c6f94c6045a6a75"}, + {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a4a3907011d39dbc3e37bdc5df0a8c93853c369039b59efa33a7b6669de04c60"}, + {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d224f0c4c9c98290a6990259073f496fcec1b5cc613eecbd22786d398ded3ad"}, + {file = "coverage-7.4.1-cp38-cp38-win32.whl", hash = "sha256:23f5881362dcb0e1a92b84b3c2809bdc90db892332daab81ad8f642d8ed55042"}, + {file = "coverage-7.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:a07f61fc452c43cd5328b392e52555f7d1952400a1ad09086c4a8addccbd138d"}, + {file = "coverage-7.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8e738a492b6221f8dcf281b67129510835461132b03024830ac0e554311a5c54"}, + {file = "coverage-7.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46342fed0fff72efcda77040b14728049200cbba1279e0bf1188f1f2078c1d70"}, + {file = "coverage-7.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9641e21670c68c7e57d2053ddf6c443e4f0a6e18e547e86af3fad0795414a628"}, + {file = "coverage-7.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb2c2688ed93b027eb0d26aa188ada34acb22dceea256d76390eea135083950"}, + {file = "coverage-7.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d12c923757de24e4e2110cf8832d83a886a4cf215c6e61ed506006872b43a6d1"}, + {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0491275c3b9971cdbd28a4595c2cb5838f08036bca31765bad5e17edf900b2c7"}, + {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:8dfc5e195bbef80aabd81596ef52a1277ee7143fe419efc3c4d8ba2754671756"}, + {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1a78b656a4d12b0490ca72651fe4d9f5e07e3c6461063a9b6265ee45eb2bdd35"}, + {file = "coverage-7.4.1-cp39-cp39-win32.whl", hash = "sha256:f90515974b39f4dea2f27c0959688621b46d96d5a626cf9c53dbc653a895c05c"}, + {file = "coverage-7.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:64e723ca82a84053dd7bfcc986bdb34af8d9da83c521c19d6b472bc6880e191a"}, + {file = "coverage-7.4.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:32a8d985462e37cfdab611a6f95b09d7c091d07668fdc26e47a725ee575fe166"}, + {file = "coverage-7.4.1.tar.gz", hash = "sha256:1ed4b95480952b1a26d863e546fa5094564aa0065e1e5f0d4d0041f293251d04"}, ] [package.dependencies] @@ -848,8 +820,6 @@ files = [ [package.dependencies] datadog = ">=0.41.0,<1.0.0" ddtrace = ">=2.3.1" -importlib_metadata = {version = "*", markers = "python_version < \"3.8\""} -typing_extensions = {version = ">=4.0,<5.0", markers = "python_version < \"3.8\""} urllib3 = [ {version = "<2.0.0", markers = "python_version < \"3.11\""}, {version = "<2.1.0", markers = "python_version >= \"3.11\""}, @@ -945,14 +915,10 @@ files = [ [package.dependencies] attrs = ">=20" -bytecode = [ - {version = ">=0.13.0,<0.14.0", markers = "python_version == \"3.7\""}, - {version = "*", markers = "python_version >= \"3.8\""}, -] +bytecode = {version = "*", markers = "python_version >= \"3.8\""} cattrs = "*" ddsketch = ">=2.0.1" envier = "*" -importlib-metadata = {version = "<=6.5.0", markers = "python_version < \"3.8\""} opentelemetry-api = ">=1" protobuf = ">=3" setuptools = {version = "*", markers = "python_version >= \"3.12\""} @@ -1141,7 +1107,6 @@ files = [ [package.dependencies] gitdb = ">=4.0.1,<5" -typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.8\""} [package.extras] test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "sumtypes"] @@ -1157,44 +1122,42 @@ files = [ {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, ] -[package.dependencies] -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} - [[package]] name = "httpcore" -version = "0.17.3" +version = "1.0.2" description = "A minimal low-level HTTP client." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "httpcore-0.17.3-py3-none-any.whl", hash = "sha256:c2789b767ddddfa2a5782e3199b2b7f6894540b17b16ec26b2c4d8e103510b87"}, - {file = "httpcore-0.17.3.tar.gz", hash = "sha256:a6f30213335e34c1ade7be6ec7c47f19f50c56db36abef1a9dfa3815b1cb3888"}, + {file = "httpcore-1.0.2-py3-none-any.whl", hash = "sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7"}, + {file = "httpcore-1.0.2.tar.gz", hash = "sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535"}, ] [package.dependencies] -anyio = ">=3.0,<5.0" certifi = "*" h11 = ">=0.13,<0.15" -sniffio = "==1.*" [package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<0.23.0)"] [[package]] name = "httpx" -version = "0.24.1" +version = "0.26.0" description = "The next generation HTTP client." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "httpx-0.24.1-py3-none-any.whl", hash = "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd"}, - {file = "httpx-0.24.1.tar.gz", hash = "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd"}, + {file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"}, + {file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"}, ] [package.dependencies] +anyio = "*" certifi = "*" -httpcore = ">=0.15.0,<0.18.0" +httpcore = "==1.*" idna = "*" sniffio = "*" @@ -1340,7 +1303,6 @@ files = [ ] [package.dependencies] -typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] @@ -1379,20 +1341,17 @@ files = [ [[package]] name = "isort" -version = "5.11.5" +version = "5.13.2" description = "A Python utility / library to sort Python imports." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.8.0" files = [ - {file = "isort-5.11.5-py3-none-any.whl", hash = "sha256:ba1d72fb2595a01c7895a5128f9585a5cc4b6d395f1c8d514989b9a7eb2a8746"}, - {file = "isort-5.11.5.tar.gz", hash = "sha256:6be1f76a507cb2ecf16c7cf14a37e41609ca082330be4e3436a18ef74add55db"}, + {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, + {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, ] [package.extras] -colors = ["colorama (>=0.4.3,<0.5.0)"] -pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] -plugins = ["setuptools"] -requirements-deprecated-finder = ["pip-api", "pipreqs"] +colors = ["colorama (>=0.4.6)"] [[package]] name = "jinja2" @@ -1440,23 +1399,23 @@ pbr = "*" [[package]] name = "jsii" -version = "1.91.0" +version = "1.94.0" description = "Python client for jsii runtime" optional = false -python-versions = "~=3.7" +python-versions = "~=3.8" files = [ - {file = "jsii-1.91.0-py3-none-any.whl", hash = "sha256:2905a4ea030ae7289b859e97003c01f4569650b4865c51e7f83d975b95c5b20a"}, - {file = "jsii-1.91.0.tar.gz", hash = "sha256:9600ac7d04b237ee229c74ffde65ece27202ceec5df5e7eebd88a532d2cb28d6"}, + {file = "jsii-1.94.0-py3-none-any.whl", hash = "sha256:1105bae271ae47c27cf31c1565c5157306efed5ad9323c9a27336f962f465716"}, + {file = "jsii-1.94.0.tar.gz", hash = "sha256:175abc356603d98f18ab6f6aa74bfeae253e4e56340aef9dc40bbb1a6a59868b"}, ] [package.dependencies] attrs = ">=21.2,<24.0" -cattrs = ">=1.8,<23.2" +cattrs = ">=1.8,<23.3" importlib-resources = ">=5.2.0" publication = ">=0.0.3" python-dateutil = "*" typeguard = ">=2.13.3,<2.14.0" -typing-extensions = ">=3.7,<5.0" +typing-extensions = ">=3.8,<5.0" [[package]] name = "jsonpatch" @@ -1497,9 +1456,6 @@ files = [ {file = "jsonpickle-3.0.2.tar.gz", hash = "sha256:e37abba4bfb3ca4a4647d28bb9f4706436f7b46c8a8333b4a718abafa8e46b37"}, ] -[package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} - [package.extras] docs = ["jaraco.packaging (>=3.2)", "rst.linker (>=1.9)", "sphinx"] testing = ["ecdsa", "feedparser", "gmpy2", "numpy", "pandas", "pymongo", "pytest (>=3.5,!=3.7.3)", "pytest-black-multipy", "pytest-checkdocs (>=1.2.3)", "pytest-cov", "pytest-flake8 (>=1.1.1)", "scikit-learn", "sqlalchemy"] @@ -1529,11 +1485,9 @@ files = [ [package.dependencies] attrs = ">=17.4.0" -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] @@ -1565,7 +1519,6 @@ files = [ ] [package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} MarkupSafe = ">=0.9.2" [package.extras] @@ -1621,7 +1574,6 @@ files = [ [package.dependencies] mdurl = ">=0.1,<1.0" -typing_extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} [package.extras] benchmarking = ["psutil", "pytest", "pytest-benchmark"] @@ -1770,7 +1722,6 @@ pathspec = ">=0.11.1" platformdirs = ">=2.2.0" pyyaml = ">=5.1" pyyaml-env-tag = ">=0.1" -typing-extensions = {version = ">=3.10", markers = "python_version < \"3.8\""} watchdog = ">=2.0" [package.extras] @@ -1846,49 +1797,49 @@ tests = ["pytest (>=4.6)"] [[package]] name = "mypy" -version = "1.4.1" +version = "1.8.0" description = "Optional static typing for Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:566e72b0cd6598503e48ea610e0052d1b8168e60a46e0bfd34b3acf2d57f96a8"}, - {file = "mypy-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ca637024ca67ab24a7fd6f65d280572c3794665eaf5edcc7e90a866544076878"}, - {file = "mypy-1.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dde1d180cd84f0624c5dcaaa89c89775550a675aff96b5848de78fb11adabcd"}, - {file = "mypy-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8c4d8e89aa7de683e2056a581ce63c46a0c41e31bd2b6d34144e2c80f5ea53dc"}, - {file = "mypy-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:bfdca17c36ae01a21274a3c387a63aa1aafe72bff976522886869ef131b937f1"}, - {file = "mypy-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7549fbf655e5825d787bbc9ecf6028731973f78088fbca3a1f4145c39ef09462"}, - {file = "mypy-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:98324ec3ecf12296e6422939e54763faedbfcc502ea4a4c38502082711867258"}, - {file = "mypy-1.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:141dedfdbfe8a04142881ff30ce6e6653c9685b354876b12e4fe6c78598b45e2"}, - {file = "mypy-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8207b7105829eca6f3d774f64a904190bb2231de91b8b186d21ffd98005f14a7"}, - {file = "mypy-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:16f0db5b641ba159eff72cff08edc3875f2b62b2fa2bc24f68c1e7a4e8232d01"}, - {file = "mypy-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:470c969bb3f9a9efcedbadcd19a74ffb34a25f8e6b0e02dae7c0e71f8372f97b"}, - {file = "mypy-1.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5952d2d18b79f7dc25e62e014fe5a23eb1a3d2bc66318df8988a01b1a037c5b"}, - {file = "mypy-1.4.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:190b6bab0302cec4e9e6767d3eb66085aef2a1cc98fe04936d8a42ed2ba77bb7"}, - {file = "mypy-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9d40652cc4fe33871ad3338581dca3297ff5f2213d0df345bcfbde5162abf0c9"}, - {file = "mypy-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:01fd2e9f85622d981fd9063bfaef1aed6e336eaacca00892cd2d82801ab7c042"}, - {file = "mypy-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2460a58faeea905aeb1b9b36f5065f2dc9a9c6e4c992a6499a2360c6c74ceca3"}, - {file = "mypy-1.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2746d69a8196698146a3dbe29104f9eb6a2a4d8a27878d92169a6c0b74435b6"}, - {file = "mypy-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae704dcfaa180ff7c4cfbad23e74321a2b774f92ca77fd94ce1049175a21c97f"}, - {file = "mypy-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:43d24f6437925ce50139a310a64b2ab048cb2d3694c84c71c3f2a1626d8101dc"}, - {file = "mypy-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c482e1246726616088532b5e964e39765b6d1520791348e6c9dc3af25b233828"}, - {file = "mypy-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:43b592511672017f5b1a483527fd2684347fdffc041c9ef53428c8dc530f79a3"}, - {file = "mypy-1.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34a9239d5b3502c17f07fd7c0b2ae6b7dd7d7f6af35fbb5072c6208e76295816"}, - {file = "mypy-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5703097c4936bbb9e9bce41478c8d08edd2865e177dc4c52be759f81ee4dd26c"}, - {file = "mypy-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e02d700ec8d9b1859790c0475df4e4092c7bf3272a4fd2c9f33d87fac4427b8f"}, - {file = "mypy-1.4.1-py3-none-any.whl", hash = "sha256:45d32cec14e7b97af848bddd97d85ea4f0db4d5a149ed9676caa4eb2f7402bb4"}, - {file = "mypy-1.4.1.tar.gz", hash = "sha256:9bbcd9ab8ea1f2e1c8031c21445b511442cc45c89951e49bbf852cbb70755b1b"}, + {file = "mypy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3"}, + {file = "mypy-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4"}, + {file = "mypy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d"}, + {file = "mypy-1.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9"}, + {file = "mypy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410"}, + {file = "mypy-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae"}, + {file = "mypy-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3"}, + {file = "mypy-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817"}, + {file = "mypy-1.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d"}, + {file = "mypy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835"}, + {file = "mypy-1.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd"}, + {file = "mypy-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55"}, + {file = "mypy-1.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218"}, + {file = "mypy-1.8.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3"}, + {file = "mypy-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e"}, + {file = "mypy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6"}, + {file = "mypy-1.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66"}, + {file = "mypy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6"}, + {file = "mypy-1.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d"}, + {file = "mypy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02"}, + {file = "mypy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8"}, + {file = "mypy-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259"}, + {file = "mypy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b"}, + {file = "mypy-1.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592"}, + {file = "mypy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a"}, + {file = "mypy-1.8.0-py3-none-any.whl", hash = "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d"}, + {file = "mypy-1.8.0.tar.gz", hash = "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07"}, ] [package.dependencies] mypy-extensions = ">=1.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""} typing-extensions = ">=4.1.0" [package.extras] dmypy = ["psutil (>=4.0)"] install-types = ["pip"] -python2 = ["typed-ast (>=1.4.0,<2)"] +mypyc = ["setuptools (>=50)"] reports = ["lxml"] [[package]] @@ -1907,13 +1858,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-appconfigdata" -version = "1.34.0" -description = "Type annotations for boto3.AppConfigData 1.34.0 service generated with mypy-boto3-builder 7.21.0" +version = "1.34.24" +description = "Type annotations for boto3.AppConfigData 1.34.24 service generated with mypy-boto3-builder 7.23.1" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-boto3-appconfigdata-1.34.0.tar.gz", hash = "sha256:5b48444398bc11ff9cb80659e67051689840cd40bf883ab06c1d7a4570b576ad"}, - {file = "mypy_boto3_appconfigdata-1.34.0-py3-none-any.whl", hash = "sha256:07972612091d388b22aeac1353475ebc1199a52f5ce80fba0e4d5d1201b3907b"}, + {file = "mypy-boto3-appconfigdata-1.34.24.tar.gz", hash = "sha256:a52a35430e9928dd17cc4465091982b6f2443a383277e6bcdade90de93da53c4"}, + {file = "mypy_boto3_appconfigdata-1.34.24-py3-none-any.whl", hash = "sha256:229014bf41f2d98ff0c230716f45740ca9b23a369c2513cab78ad9a02f6a1515"}, ] [package.dependencies] @@ -1921,13 +1872,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-cloudformation" -version = "1.34.0" -description = "Type annotations for boto3.CloudFormation 1.34.0 service generated with mypy-boto3-builder 7.21.0" +version = "1.34.32" +description = "Type annotations for boto3.CloudFormation 1.34.32 service generated with mypy-boto3-builder 7.23.1" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-boto3-cloudformation-1.34.0.tar.gz", hash = "sha256:9b25df9ef15d9dc8e4e892cc07aa9343f15f2ed5eb7d33eb5eb65adfa63f538f"}, - {file = "mypy_boto3_cloudformation-1.34.0-py3-none-any.whl", hash = "sha256:4e63a2bca1882971881d65983acd774c2fc636bbc5dc8c3e1f4a41c539cf3c90"}, + {file = "mypy-boto3-cloudformation-1.34.32.tar.gz", hash = "sha256:49d04c090dae3fd8289738ae592cac9d6faa5169684de40c2730b425bba2a32d"}, + {file = "mypy_boto3_cloudformation-1.34.32-py3-none-any.whl", hash = "sha256:bfe5ec405eae6dae31dc9874729eef5e668e634eae8972032f00400d17bd2c7d"}, ] [package.dependencies] @@ -1949,13 +1900,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-dynamodb" -version = "1.34.0" -description = "Type annotations for boto3.DynamoDB 1.34.0 service generated with mypy-boto3-builder 7.21.0" +version = "1.34.34" +description = "Type annotations for boto3.DynamoDB 1.34.34 service generated with mypy-boto3-builder 7.23.1" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-boto3-dynamodb-1.34.0.tar.gz", hash = "sha256:c0d98d7e83b0bc22e5039f703889fb96202d818171c4206fd31e665a37654e84"}, - {file = "mypy_boto3_dynamodb-1.34.0-py3-none-any.whl", hash = "sha256:76869c3fec882ddeeaca485074e302bf38c3b61103664d665dfed9425234ff75"}, + {file = "mypy-boto3-dynamodb-1.34.34.tar.gz", hash = "sha256:023b0284027ab5f4e5c912dfae86583c62b0e6c8b1d34fad8c6fba37f9baf17b"}, + {file = "mypy_boto3_dynamodb-1.34.34-py3-none-any.whl", hash = "sha256:fb5e49ec0632ff9c15be3ce25302cdd7a917ffa0a80c49f30e3a136ecc9601f0"}, ] [package.dependencies] @@ -1977,13 +1928,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-logs" -version = "1.34.0" -description = "Type annotations for boto3.CloudWatchLogs 1.34.0 service generated with mypy-boto3-builder 7.21.0" +version = "1.34.16" +description = "Type annotations for boto3.CloudWatchLogs 1.34.16 service generated with mypy-boto3-builder 7.23.1" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-boto3-logs-1.34.0.tar.gz", hash = "sha256:a852bf6c48733a51c324ca97da042bfe4c66b0d33aabe042fb27d3092572d55b"}, - {file = "mypy_boto3_logs-1.34.0-py3-none-any.whl", hash = "sha256:cb2d29096d3b07d7d508fa1f236f9cd15c292d41c8807aba7347627868e7ebdc"}, + {file = "mypy-boto3-logs-1.34.16.tar.gz", hash = "sha256:fff912fd8e9b7ce2bd5ea64c7f3e1f07885660226190f86353083836338a2d2a"}, + {file = "mypy_boto3_logs-1.34.16-py3-none-any.whl", hash = "sha256:2f0c918a59fbac279117bef67666aafd7d6ebdd5fbc7015352206553afb82c40"}, ] [package.dependencies] @@ -1991,13 +1942,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-s3" -version = "1.34.0" -description = "Type annotations for boto3.S3 1.34.0 service generated with mypy-boto3-builder 7.21.0" +version = "1.34.14" +description = "Type annotations for boto3.S3 1.34.14 service generated with mypy-boto3-builder 7.21.0" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-boto3-s3-1.34.0.tar.gz", hash = "sha256:7644a00e096ebb1c3292551059f64ff8329625dacd40827ced9481b14d64c733"}, - {file = "mypy_boto3_s3-1.34.0-py3-none-any.whl", hash = "sha256:633876d2a96dbb924f9667084316c1759bff40c19a9a38313d5a4e825c5fc641"}, + {file = "mypy-boto3-s3-1.34.14.tar.gz", hash = "sha256:71c39ab0623cdb442d225b71c1783f6a513cff4c4a13505a2efbb2e3aff2e965"}, + {file = "mypy_boto3_s3-1.34.14-py3-none-any.whl", hash = "sha256:f9669ecd182d5bf3532f5f2dcc5e5237776afe157ad5a0b37b26d6bec5fcc432"}, ] [package.dependencies] @@ -2005,13 +1956,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-secretsmanager" -version = "1.34.0" -description = "Type annotations for boto3.SecretsManager 1.34.0 service generated with mypy-boto3-builder 7.21.0" +version = "1.34.17" +description = "Type annotations for boto3.SecretsManager 1.34.17 service generated with mypy-boto3-builder 7.23.1" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-boto3-secretsmanager-1.34.0.tar.gz", hash = "sha256:f7c1a99a28e650ac91834db69a8dabe6734f9ace92f1d7a2d366160a11401133"}, - {file = "mypy_boto3_secretsmanager-1.34.0-py3-none-any.whl", hash = "sha256:d3b0c26f4264775a2505cbd4a73a4efd5c4a151d8fcdcf938683afb1bf717a32"}, + {file = "mypy-boto3-secretsmanager-1.34.17.tar.gz", hash = "sha256:a547932d99c3f711b27b9ea1c38fc063050910c0bf6c8eb346abd96ace61668e"}, + {file = "mypy_boto3_secretsmanager-1.34.17-py3-none-any.whl", hash = "sha256:0dbd1cdbe7992324c3414cccf0256e3905827bbf1f6a8d58c255635f6a2b4bfb"}, ] [package.dependencies] @@ -2019,13 +1970,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-ssm" -version = "1.34.0" -description = "Type annotations for boto3.SSM 1.34.0 service generated with mypy-boto3-builder 7.21.0" +version = "1.34.32" +description = "Type annotations for boto3.SSM 1.34.32 service generated with mypy-boto3-builder 7.23.1" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-boto3-ssm-1.34.0.tar.gz", hash = "sha256:ae82936d77496f7958dc25d5db7d48f63b164cac03686c60475c709107deafec"}, - {file = "mypy_boto3_ssm-1.34.0-py3-none-any.whl", hash = "sha256:e2c34db563851939cab1f12fb392be904f83146af88f515c5cd50bf6c612dda4"}, + {file = "mypy-boto3-ssm-1.34.32.tar.gz", hash = "sha256:1d78f8bfb85d4bfb820046b7c864b75e2ef1a04ea7fed88b4d6d6abf252077e6"}, + {file = "mypy_boto3_ssm-1.34.32-py3-none-any.whl", hash = "sha256:185e46fa5996843e34a5c7fb5e2129df57a37fca3187daa1ab81996d5633c772"}, ] [package.dependencies] @@ -2169,27 +2120,21 @@ files = [ {file = "platformdirs-4.0.0.tar.gz", hash = "sha256:cb633b2bcf10c51af60beb0ab06d2f1d69064b43abf4c185ca6b28865f3f9731"}, ] -[package.dependencies] -typing-extensions = {version = ">=4.7.1", markers = "python_version < \"3.8\""} - [package.extras] docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] [[package]] name = "pluggy" -version = "1.2.0" +version = "1.4.0" description = "plugin and hook calling mechanisms for python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, - {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, + {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, + {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, ] -[package.dependencies] -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} - [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] @@ -2394,22 +2339,21 @@ files = [ [[package]] name = "pytest" -version = "7.4.4" +version = "8.0.0" description = "pytest: simple powerful testing with Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, - {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, + {file = "pytest-8.0.0-py3-none-any.whl", hash = "sha256:50fb9cbe836c3f20f0dfa99c565201fb75dc54c8d76373cd1bde06b06657bdb6"}, + {file = "pytest-8.0.0.tar.gz", hash = "sha256:249b1b0864530ba251b7438274c4d251c58d868edaaec8762893ad4a0d71c36c"}, ] [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<2.0" +pluggy = ">=1.3.0,<2.0" tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] @@ -2428,7 +2372,6 @@ files = [ [package.dependencies] pytest = ">=7.0.0" -typing-extensions = {version = ">=3.7.2", markers = "python_version < \"3.8\""} [package.extras] docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] @@ -2676,8 +2619,6 @@ files = [ [package.dependencies] async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2\""} -importlib-metadata = {version = ">=1.0", markers = "python_version < \"3.8\""} -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] hiredis = ["hiredis (>=1.0.0)"] @@ -2997,7 +2938,6 @@ files = [ ] [package.dependencies] -importlib-metadata = {version = ">=1.7.0", markers = "python_version < \"3.8\""} pbr = ">=2.0.0,<2.1.0 || >2.1.0" [[package]] @@ -3059,56 +2999,6 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] -[[package]] -name = "typed-ast" -version = "1.5.5" -description = "a fork of Python 2 and 3 ast modules with type comment support" -optional = false -python-versions = ">=3.6" -files = [ - {file = "typed_ast-1.5.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4bc1efe0ce3ffb74784e06460f01a223ac1f6ab31c6bc0376a21184bf5aabe3b"}, - {file = "typed_ast-1.5.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5f7a8c46a8b333f71abd61d7ab9255440d4a588f34a21f126bbfc95f6049e686"}, - {file = "typed_ast-1.5.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:597fc66b4162f959ee6a96b978c0435bd63791e31e4f410622d19f1686d5e769"}, - {file = "typed_ast-1.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d41b7a686ce653e06c2609075d397ebd5b969d821b9797d029fccd71fdec8e04"}, - {file = "typed_ast-1.5.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5fe83a9a44c4ce67c796a1b466c270c1272e176603d5e06f6afbc101a572859d"}, - {file = "typed_ast-1.5.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d5c0c112a74c0e5db2c75882a0adf3133adedcdbfd8cf7c9d6ed77365ab90a1d"}, - {file = "typed_ast-1.5.5-cp310-cp310-win_amd64.whl", hash = "sha256:e1a976ed4cc2d71bb073e1b2a250892a6e968ff02aa14c1f40eba4f365ffec02"}, - {file = "typed_ast-1.5.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c631da9710271cb67b08bd3f3813b7af7f4c69c319b75475436fcab8c3d21bee"}, - {file = "typed_ast-1.5.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b445c2abfecab89a932b20bd8261488d574591173d07827c1eda32c457358b18"}, - {file = "typed_ast-1.5.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc95ffaaab2be3b25eb938779e43f513e0e538a84dd14a5d844b8f2932593d88"}, - {file = "typed_ast-1.5.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61443214d9b4c660dcf4b5307f15c12cb30bdfe9588ce6158f4a005baeb167b2"}, - {file = "typed_ast-1.5.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6eb936d107e4d474940469e8ec5b380c9b329b5f08b78282d46baeebd3692dc9"}, - {file = "typed_ast-1.5.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e48bf27022897577d8479eaed64701ecaf0467182448bd95759883300ca818c8"}, - {file = "typed_ast-1.5.5-cp311-cp311-win_amd64.whl", hash = "sha256:83509f9324011c9a39faaef0922c6f720f9623afe3fe220b6d0b15638247206b"}, - {file = "typed_ast-1.5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:44f214394fc1af23ca6d4e9e744804d890045d1643dd7e8229951e0ef39429b5"}, - {file = "typed_ast-1.5.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:118c1ce46ce58fda78503eae14b7664163aa735b620b64b5b725453696f2a35c"}, - {file = "typed_ast-1.5.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be4919b808efa61101456e87f2d4c75b228f4e52618621c77f1ddcaae15904fa"}, - {file = "typed_ast-1.5.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:fc2b8c4e1bc5cd96c1a823a885e6b158f8451cf6f5530e1829390b4d27d0807f"}, - {file = "typed_ast-1.5.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:16f7313e0a08c7de57f2998c85e2a69a642e97cb32f87eb65fbfe88381a5e44d"}, - {file = "typed_ast-1.5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:2b946ef8c04f77230489f75b4b5a4a6f24c078be4aed241cfabe9cbf4156e7e5"}, - {file = "typed_ast-1.5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2188bc33d85951ea4ddad55d2b35598b2709d122c11c75cffd529fbc9965508e"}, - {file = "typed_ast-1.5.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0635900d16ae133cab3b26c607586131269f88266954eb04ec31535c9a12ef1e"}, - {file = "typed_ast-1.5.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57bfc3cf35a0f2fdf0a88a3044aafaec1d2f24d8ae8cd87c4f58d615fb5b6311"}, - {file = "typed_ast-1.5.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:fe58ef6a764de7b4b36edfc8592641f56e69b7163bba9f9c8089838ee596bfb2"}, - {file = "typed_ast-1.5.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d09d930c2d1d621f717bb217bf1fe2584616febb5138d9b3e8cdd26506c3f6d4"}, - {file = "typed_ast-1.5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:d40c10326893ecab8a80a53039164a224984339b2c32a6baf55ecbd5b1df6431"}, - {file = "typed_ast-1.5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fd946abf3c31fb50eee07451a6aedbfff912fcd13cf357363f5b4e834cc5e71a"}, - {file = "typed_ast-1.5.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ed4a1a42df8a3dfb6b40c3d2de109e935949f2f66b19703eafade03173f8f437"}, - {file = "typed_ast-1.5.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:045f9930a1550d9352464e5149710d56a2aed23a2ffe78946478f7b5416f1ede"}, - {file = "typed_ast-1.5.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:381eed9c95484ceef5ced626355fdc0765ab51d8553fec08661dce654a935db4"}, - {file = "typed_ast-1.5.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bfd39a41c0ef6f31684daff53befddae608f9daf6957140228a08e51f312d7e6"}, - {file = "typed_ast-1.5.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8c524eb3024edcc04e288db9541fe1f438f82d281e591c548903d5b77ad1ddd4"}, - {file = "typed_ast-1.5.5-cp38-cp38-win_amd64.whl", hash = "sha256:7f58fabdde8dcbe764cef5e1a7fcb440f2463c1bbbec1cf2a86ca7bc1f95184b"}, - {file = "typed_ast-1.5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:042eb665ff6bf020dd2243307d11ed626306b82812aba21836096d229fdc6a10"}, - {file = "typed_ast-1.5.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:622e4a006472b05cf6ef7f9f2636edc51bda670b7bbffa18d26b255269d3d814"}, - {file = "typed_ast-1.5.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1efebbbf4604ad1283e963e8915daa240cb4bf5067053cf2f0baadc4d4fb51b8"}, - {file = "typed_ast-1.5.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0aefdd66f1784c58f65b502b6cf8b121544680456d1cebbd300c2c813899274"}, - {file = "typed_ast-1.5.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:48074261a842acf825af1968cd912f6f21357316080ebaca5f19abbb11690c8a"}, - {file = "typed_ast-1.5.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:429ae404f69dc94b9361bb62291885894b7c6fb4640d561179548c849f8492ba"}, - {file = "typed_ast-1.5.5-cp39-cp39-win_amd64.whl", hash = "sha256:335f22ccb244da2b5c296e6f96b06ee9bed46526db0de38d2f0e5a6597b81155"}, - {file = "typed_ast-1.5.5.tar.gz", hash = "sha256:94282f7a354f36ef5dbce0ef3467ebf6a258e370ab33d5b40c249fa996e590dd"}, -] - [[package]] name = "typeguard" version = "2.13.3" @@ -3140,13 +3030,13 @@ cryptography = ">=35.0.0" [[package]] name = "types-python-dateutil" -version = "2.8.19.14" +version = "2.8.19.20240106" description = "Typing stubs for python-dateutil" optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "types-python-dateutil-2.8.19.14.tar.gz", hash = "sha256:1f4f10ac98bb8b16ade9dbee3518d9ace017821d94b057a425b069f834737f4b"}, - {file = "types_python_dateutil-2.8.19.14-py3-none-any.whl", hash = "sha256:f977b8de27787639986b4e28963263fd0e5158942b3ecef91b9335c130cb1ce9"}, + {file = "types-python-dateutil-2.8.19.20240106.tar.gz", hash = "sha256:1f8db221c3b98e6ca02ea83a58371b22c374f42ae5bbdf186db9c9a76581459f"}, + {file = "types_python_dateutil-2.8.19.20240106-py3-none-any.whl", hash = "sha256:efbbdc54590d0f16152fa103c9879c7d4a00e82078f6e2cf01769042165acaa2"}, ] [[package]] @@ -3435,5 +3325,5 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" -python-versions = "^3.7.4" -content-hash = "ed9d43fd5827d270530b7e9eb60fb2e398e9d42b4317035396bb51c52485d313" +python-versions = ">=3.8,<4.0.0" +content-hash = "1eb623d82065a5ab34897f92712b38bb28e8d316ed307a38ece0427a58d80545" diff --git a/pyproject.toml b/pyproject.toml index 12b64b23cbd..36767102e12 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,6 @@ classifiers = [ "Intended Audience :: Developers", "License :: OSI Approved :: MIT No Attribution License (MIT-0)", "Natural Language :: English", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", @@ -39,7 +38,7 @@ license = "MIT" "Releases" = "https://github.com/aws-powertools/powertools-lambda-python/releases" [tool.poetry.dependencies] -python = "^3.7.4" +python = ">=3.8,<4.0.0" aws-xray-sdk = { version = "^2.8.0", optional = true } fastjsonschema = { version = "^2.14.5", optional = true } pydantic = { version = "^1.8.2", optional = true } @@ -49,13 +48,14 @@ typing-extensions = "^4.6.2" datadog-lambda = { version = ">=4.77,<6.0", optional = true } aws-encryption-sdk = { version = "^3.1.1", optional = true } jsonpath-ng = { version = "^1.6.0", optional = true } +aws-cdk-lib = "^2.126.0" [tool.poetry.dev-dependencies] -coverage = {extras = ["toml"], version = "^7.2"} -pytest = "^7.4.4" +coverage = {extras = ["toml"], version = "^7.4"} +pytest = "^8.0.0" black = "^23.3" boto3 = "^1.26.164" -isort = "^5.11.5" +isort = "^5.13.2" pytest-cov = "^4.1.0" pytest-mock = "^3.11.1" pdoc3 = "^0.10.0" @@ -72,21 +72,21 @@ aws-cdk-lib = "^2.111.0" "aws-cdk.aws-apigatewayv2-authorizers-alpha" = "^2.38.1-alpha.0" pytest-benchmark = "^4.0.0" mypy-boto3-appconfig = "^1.34.0" -mypy-boto3-cloudformation = "^1.34.0" +mypy-boto3-cloudformation = "^1.34.32" mypy-boto3-cloudwatch = "^1.34.0" -mypy-boto3-dynamodb = "^1.34.0" +mypy-boto3-dynamodb = "^1.34.34" mypy-boto3-lambda = "^1.34.0" -mypy-boto3-logs = "^1.34.0" -mypy-boto3-secretsmanager = "^1.34.0" -mypy-boto3-ssm = "^1.34.0" -mypy-boto3-s3 = "^1.34.0" +mypy-boto3-logs = "^1.34.16" +mypy-boto3-secretsmanager = "^1.34.17" +mypy-boto3-ssm = "^1.34.32" +mypy-boto3-s3 = "^1.34.14" mypy-boto3-xray = "^1.34.0" types-requests = "^2.31.0" typing-extensions = "^4.6.2" mkdocs-material = "^9.2.7" filelock = "^3.12.2" checksumdir = "^1.2.0" -mypy-boto3-appconfigdata = "^1.34.0" +mypy-boto3-appconfigdata = "^1.34.24" ijson = "^3.2.2" typed-ast = { version = "^1.5.5", python = "< 3.8"} hvac = "^1.2.1" @@ -105,10 +105,10 @@ datadog = ["datadog-lambda"] datamasking = ["aws-encryption-sdk", "jsonpath-ng"] [tool.poetry.group.dev.dependencies] -cfn-lint = "0.83.8" +cfn-lint = "0.85.0" mypy = "^1.1.1" types-python-dateutil = "^2.8.19.6" -httpx = ">=0.23.3,<0.25.0" +httpx = ">=0.23.3,<0.27.0" sentry-sdk = "^1.22.2" ruff = ">=0.0.272,<0.2.1" retry2 = "^0.9.5" diff --git a/tests/e2e/idempotency_redis/conftest.py b/tests/e2e/idempotency_redis/conftest.py index 6f3183f02dd..0e12288fe9a 100644 --- a/tests/e2e/idempotency_redis/conftest.py +++ b/tests/e2e/idempotency_redis/conftest.py @@ -1,5 +1,7 @@ import pytest +from tests.e2e.idempotency_redis.infrastructure import IdempotencyRedisServerlessStack + @pytest.fixture(autouse=True, scope="package") def infrastructure(): @@ -11,5 +13,8 @@ def infrastructure(): CloudFormation Outputs from deployed infrastructure """ - # MAINTENANCE: Add the Stack constructor when Python 3.7 is dropped - return None + stack = IdempotencyRedisServerlessStack() + try: + yield stack.deploy() + finally: + stack.delete() diff --git a/tests/e2e/idempotency_redis/test_idempotency_redis.py b/tests/e2e/idempotency_redis/test_idempotency_redis.py index 7a8c55374f8..4b5840ac477 100644 --- a/tests/e2e/idempotency_redis/test_idempotency_redis.py +++ b/tests/e2e/idempotency_redis/test_idempotency_redis.py @@ -6,8 +6,6 @@ from tests.e2e.utils import data_fetcher from tests.e2e.utils.data_fetcher.common import GetLambdaResponseOptions, get_lambda_response_in_parallel -pytest.skip(reason="Redis tests disabled until we deprecate Python 3.7.", allow_module_level=True) - @pytest.fixture def ttl_cache_expiration_handler_fn_arn(infrastructure: dict) -> str: diff --git a/tests/e2e/utils/infrastructure.py b/tests/e2e/utils/infrastructure.py index 5adef6133f8..1137fc222a3 100644 --- a/tests/e2e/utils/infrastructure.py +++ b/tests/e2e/utils/infrastructure.py @@ -251,9 +251,7 @@ def _create_temp_cdk_app(self): def _determine_runtime_version(self) -> Runtime: """Determine Python runtime version based on the current Python interpreter""" version = sys.version_info - if version.major == 3 and version.minor == 7: - return Runtime.PYTHON_3_7 - elif version.major == 3 and version.minor == 8: + if version.major == 3 and version.minor == 8: return Runtime.PYTHON_3_8 elif version.major == 3 and version.minor == 9: return Runtime.PYTHON_3_9 diff --git a/tests/functional/event_handler/test_appsync.py b/tests/functional/event_handler/test_appsync.py index 54695eba240..5699e560065 100644 --- a/tests/functional/event_handler/test_appsync.py +++ b/tests/functional/event_handler/test_appsync.py @@ -1,5 +1,4 @@ import asyncio -import sys import pytest @@ -121,7 +120,6 @@ def get_locations(name: str, description: str = ""): assert result2 == "value2description" -@pytest.mark.skipif(sys.version_info < (3, 8), reason="only for python versions that support asyncio.run") def test_resolver_async(): # GIVEN app = AppSyncResolver() diff --git a/tests/functional/idempotency/test_idempotency.py b/tests/functional/idempotency/test_idempotency.py index 905248011e6..f5b441e5e91 100644 --- a/tests/functional/idempotency/test_idempotency.py +++ b/tests/functional/idempotency/test_idempotency.py @@ -1,6 +1,5 @@ import copy import datetime -import sys import warnings from unittest.mock import MagicMock @@ -143,7 +142,6 @@ def lambda_handler(event, context): stubber.deactivate() -@pytest.mark.skipif(sys.version_info < (3, 8), reason="issue with pytest mock lib for < 3.8") @pytest.mark.parametrize("idempotency_config", [{"use_local_cache": True}], indirect=True) def test_idempotent_lambda_in_progress_with_cache( idempotency_config: IdempotencyConfig, @@ -1713,7 +1711,6 @@ def test_invalid_dynamodb_persistence_layer(): assert str(ve.value) == "key_attr [id] and sort_key_attr [id] cannot be the same!" -@pytest.mark.skipif(sys.version_info < (3, 7), reason="requires python3.7 or higher for dataclasses") def test_idempotent_function_dataclasses(): # Scenario _prepare_data should convert a python dataclasses to a dict dataclasses = get_dataclasses_lib() @@ -1747,7 +1744,6 @@ def test_idempotent_function_other(data): assert _prepare_data(data) == data -@pytest.mark.skipif(sys.version_info < (3, 7), reason="requires python3.7 or higher for dataclasses") def test_idempotent_function_dataclass_with_jmespath(): # GIVEN dataclasses = get_dataclasses_lib() @@ -1773,7 +1769,6 @@ def collect_payment(payment: Payment): assert result == payment.transaction_id -@pytest.mark.skipif(sys.version_info < (3, 7), reason="requires python3.7 or higher for dataclasses") def test_idempotent_function_pydantic_with_jmespath(): # GIVEN config = IdempotencyConfig(event_key_jmespath="transaction_id", use_local_cache=True) diff --git a/tests/unit/test_tracing.py b/tests/unit/test_tracing.py index ae140eb2bee..fdb7310495b 100644 --- a/tests/unit/test_tracing.py +++ b/tests/unit/test_tracing.py @@ -1,5 +1,4 @@ import contextlib -import sys from typing import NamedTuple from unittest import mock from unittest.mock import MagicMock @@ -83,9 +82,7 @@ class InSubsegment(NamedTuple): in_subsegment = InSubsegment() in_subsegment.in_subsegment.return_value.__enter__.return_value.put_annotation = in_subsegment.put_annotation in_subsegment.in_subsegment.return_value.__enter__.return_value.put_metadata = in_subsegment.put_metadata - - if sys.version_info >= (3, 8): # 3.8 introduced AsyncMock - in_subsegment.in_subsegment.return_value.__aenter__.return_value.put_metadata = in_subsegment.put_metadata + in_subsegment.in_subsegment.return_value.__aenter__.return_value.put_metadata = in_subsegment.put_metadata yield in_subsegment