diff --git a/.github/workflows/ossf_scorecard.yml b/.github/workflows/ossf_scorecard.yml index a7d647fde0f..430767741d7 100644 --- a/.github/workflows/ossf_scorecard.yml +++ b/.github/workflows/ossf_scorecard.yml @@ -43,6 +43,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@5595ccaf912efad79be6eef63a5619ff05969be3 # v4.37.6 + uses: github/codeql-action/upload-sarif@db488ddef3bf6cb639b32c2e9a7c0a7ea8271d28 # v4.37.8 with: sarif_file: results.sarif diff --git a/.github/workflows/publish_v3_layer.yml b/.github/workflows/publish_v3_layer.yml index 456533b055e..ab2f43285e5 100644 --- a/.github/workflows/publish_v3_layer.yml +++ b/.github/workflows/publish_v3_layer.yml @@ -146,7 +146,7 @@ jobs: - name: Set up Docker Buildx id: builder - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 + uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0 with: driver: docker platforms: linux/amd64,linux/arm64 diff --git a/.github/workflows/quality_code_cdk_constructor.yml b/.github/workflows/quality_code_cdk_constructor.yml index cedb82b82bc..4dd9a631c51 100644 --- a/.github/workflows/quality_code_cdk_constructor.yml +++ b/.github/workflows/quality_code_cdk_constructor.yml @@ -57,7 +57,7 @@ jobs: # NOTE: we need QEMU to build Layer against a different architecture (e.g., ARM) - name: Set up Docker Buildx id: builder - uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0 + uses: docker/setup-buildx-action@37fe631027851001ddb9b187196cc803df7f5f0e # v4.3.0 with: driver: docker platforms: linux/amd64,linux/arm64 diff --git a/.github/workflows/secure_workflows.yml b/.github/workflows/secure_workflows.yml index 728c632d5cb..b21adc7f5df 100644 --- a/.github/workflows/secure_workflows.yml +++ b/.github/workflows/secure_workflows.yml @@ -32,7 +32,7 @@ jobs: - name: Checkout code uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Ensure 3rd party workflows have SHA pinned - uses: zgosalvez/github-actions-ensure-sha-pinned-actions@46cfe808a5f1588656ef299eedd0ce2fd7ec0dcc # v5.0.6 + uses: zgosalvez/github-actions-ensure-sha-pinned-actions@c5fc58bd0be7a4b94b73ce40250322d5b838a108 # v5.0.7 with: allowlist: | slsa-framework/slsa-github-generator diff --git a/aws_lambda_powertools/utilities/batch/exceptions.py b/aws_lambda_powertools/utilities/batch/exceptions.py index 87a2df22d6d..247388a9886 100644 --- a/aws_lambda_powertools/utilities/batch/exceptions.py +++ b/aws_lambda_powertools/utilities/batch/exceptions.py @@ -6,9 +6,9 @@ import traceback from types import TracebackType -from typing import Optional, Tuple, Type +from typing import Tuple, Type -ExceptionInfo = Tuple[Optional[Type[BaseException]], Optional[BaseException], Optional[TracebackType]] +ExceptionInfo = Tuple[Type[BaseException] | None, BaseException | None, TracebackType | None] class BaseBatchProcessingError(Exception): diff --git a/aws_lambda_powertools/utilities/batch/types.py b/aws_lambda_powertools/utilities/batch/types.py index ec543bf51ea..32e11b5ae07 100644 --- a/aws_lambda_powertools/utilities/batch/types.py +++ b/aws_lambda_powertools/utilities/batch/types.py @@ -1,7 +1,7 @@ from __future__ import annotations import sys -from typing import Optional, Type, TypedDict, Union +from typing import Type, TypedDict, Union has_pydantic = "pydantic" in sys.modules @@ -14,15 +14,16 @@ ) from aws_lambda_powertools.utilities.parser.models.kafka import KafkaRecordModel - BatchTypeModels = Optional[ + BatchTypeModels = ( Union[ Type[SqsRecordModel], Type[DynamoDBStreamRecordModel], Type[KinesisDataStreamRecordModel], Type[KafkaRecordModel], ] - ] - BatchSqsTypeModel = Optional[Type[SqsRecordModel]] + | None + ) + BatchSqsTypeModel = Type[SqsRecordModel] | None else: # pragma: no cover BatchTypeModels = "BatchTypeModels" # type: ignore BatchSqsTypeModel = "BatchSqsTypeModel" # type: ignore diff --git a/aws_lambda_powertools/utilities/idempotency/persistence/base.py b/aws_lambda_powertools/utilities/idempotency/persistence/base.py index 3d54a01f018..2271520139d 100644 --- a/aws_lambda_powertools/utilities/idempotency/persistence/base.py +++ b/aws_lambda_powertools/utilities/idempotency/persistence/base.py @@ -131,7 +131,10 @@ def _get_hashed_idempotency_key(self, data: dict[str, Any]) -> str | None: @staticmethod def is_missing_idempotency_key(data) -> bool: - if isinstance(data, (tuple, list, dict)): + if isinstance(data, dict): + # JMESPath multi-select dicts retain their keys when all selected values are missing. + return all(x is None for x in data.values()) + elif isinstance(data, (tuple, list)): return all(x is None for x in data) elif isinstance(data, (int, float, bool)): return False diff --git a/aws_lambda_powertools/utilities/idempotency/persistence/redis.py b/aws_lambda_powertools/utilities/idempotency/persistence/redis.py index 82a44e079de..ce7100bf215 100644 --- a/aws_lambda_powertools/utilities/idempotency/persistence/redis.py +++ b/aws_lambda_powertools/utilities/idempotency/persistence/redis.py @@ -425,10 +425,12 @@ def _put_in_progress_record(self, data_record: DataRecord) -> None: # (meaning the timestamp is greater than the current timestamp in milliseconds), then we have encountered # a valid in-progress record. This indicates that another process is currently handling the request, and # to maintain idempotency, we raise an error to prevent concurrent processing of the same request. - if ( - idempotency_record.status == STATUS_CONSTANTS["INPROGRESS"] - and idempotency_record.in_progress_expiry_timestamp - and idempotency_record.in_progress_expiry_timestamp > int(now.timestamp() * 1000) + # + # Without an in-progress expiry, we cannot safely distinguish an active invocation from a timed-out one. + # Fail closed until the record TTL expires, consistent with the DynamoDB persistence layer. + if idempotency_record.status == STATUS_CONSTANTS["INPROGRESS"] and ( + idempotency_record.in_progress_expiry_timestamp is None + or idempotency_record.in_progress_expiry_timestamp > int(now.timestamp() * 1000) ): raise IdempotencyItemAlreadyExistsError diff --git a/aws_lambda_powertools/utilities/parser/models/apigw.py b/aws_lambda_powertools/utilities/parser/models/apigw.py index ea01a5e8a6b..349ebbb512b 100644 --- a/aws_lambda_powertools/utilities/parser/models/apigw.py +++ b/aws_lambda_powertools/utilities/parser/models/apigw.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import Any, Dict, List, Literal, Optional, Type, Union +from typing import Any, Dict, List, Literal, Type, Union from pydantic import BaseModel, field_validator, model_validator from pydantic.networks import IPvAnyNetwork @@ -21,23 +21,23 @@ class ApiGatewayUserCert(BaseModel): class APIGatewayEventIdentity(BaseModel): - accessKey: Optional[str] = None - accountId: Optional[str] = None - apiKey: Optional[str] = None - apiKeyId: Optional[str] = None - caller: Optional[str] = None - cognitoAuthenticationProvider: Optional[str] = None - cognitoAuthenticationType: Optional[str] = None - cognitoIdentityId: Optional[str] = None - cognitoIdentityPoolId: Optional[str] = None - principalOrgId: Optional[str] = None + accessKey: str | None = None + accountId: str | None = None + apiKey: str | None = None + apiKeyId: str | None = None + caller: str | None = None + cognitoAuthenticationProvider: str | None = None + cognitoAuthenticationType: str | None = None + cognitoIdentityId: str | None = None + cognitoIdentityPoolId: str | None = None + principalOrgId: str | None = None # see #1562, temp workaround until API Gateway fixes it the Test button payload # removing it will not be considered a regression in the future sourceIp: Union[IPvAnyNetwork, str] - user: Optional[str] = None - userAgent: Optional[str] = None - userArn: Optional[str] = None - clientCert: Optional[ApiGatewayUserCert] = None + user: str | None = None + userAgent: str | None = None + userArn: str | None = None + clientCert: ApiGatewayUserCert | None = None @field_validator("sourceIp", mode="before") @classmethod @@ -46,34 +46,34 @@ def _validate_source_ip(cls, value): class APIGatewayEventAuthorizer(BaseModel): - claims: Optional[Dict[str, Any]] = None - scopes: Optional[List[str]] = None + claims: Dict[str, Any] | None = None + scopes: List[str] | None = None class APIGatewayEventRequestContext(BaseModel): accountId: str apiId: str - authorizer: Optional[APIGatewayEventAuthorizer] = None + authorizer: APIGatewayEventAuthorizer | None = None stage: str protocol: str identity: APIGatewayEventIdentity requestId: str requestTime: str requestTimeEpoch: datetime - resourceId: Optional[str] = None + resourceId: str | None = None resourcePath: str - domainName: Optional[str] = None - domainPrefix: Optional[str] = None - extendedRequestId: Optional[str] = None + domainName: str | None = None + domainPrefix: str | None = None + extendedRequestId: str | None = None httpMethod: Literal["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"] path: str - connectedAt: Optional[datetime] = None - connectionId: Optional[str] = None - eventType: Optional[Literal["CONNECT", "MESSAGE", "DISCONNECT"]] = None - messageDirection: Optional[str] = None - messageId: Optional[str] = None - routeKey: Optional[str] = None - operationName: Optional[str] = None + connectedAt: datetime | None = None + connectionId: str | None = None + eventType: Literal["CONNECT", "MESSAGE", "DISCONNECT"] | None = None + messageDirection: str | None = None + messageId: str | None = None + routeKey: str | None = None + operationName: str | None = None @model_validator(mode="before") def check_message_id(cls, values): @@ -84,19 +84,19 @@ def check_message_id(cls, values): class APIGatewayProxyEventModel(BaseModel): - version: Optional[str] = None + version: str | None = None resource: str path: str httpMethod: Literal["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"] headers: Dict[str, str] multiValueHeaders: Dict[str, List[str]] - queryStringParameters: Optional[Dict[str, str]] = None - multiValueQueryStringParameters: Optional[Dict[str, List[str]]] = None + queryStringParameters: Dict[str, str] | None = None + multiValueQueryStringParameters: Dict[str, List[str]] | None = None requestContext: APIGatewayEventRequestContext - pathParameters: Optional[Dict[str, str]] = None - stageVariables: Optional[Dict[str, str]] = None - isBase64Encoded: Optional[bool] = None - body: Optional[Union[str, Type[BaseModel]]] = None + pathParameters: Dict[str, str] | None = None + stageVariables: Dict[str, str] | None = None + isBase64Encoded: bool | None = None + body: Union[str, Type[BaseModel]] | None = None class ApiGatewayAuthorizerToken(BaseModel): diff --git a/aws_lambda_powertools/utilities/parser/models/apigw_websocket.py b/aws_lambda_powertools/utilities/parser/models/apigw_websocket.py index b9e7ecd68c7..3454d7d30a0 100644 --- a/aws_lambda_powertools/utilities/parser/models/apigw_websocket.py +++ b/aws_lambda_powertools/utilities/parser/models/apigw_websocket.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import Dict, List, Literal, Optional, Type, Union +from typing import Dict, List, Literal, Type, Union from pydantic import BaseModel, Field from pydantic.networks import IPvAnyNetwork @@ -7,7 +7,7 @@ class APIGatewayWebSocketEventIdentity(BaseModel): source_ip: IPvAnyNetwork = Field(alias="sourceIp") - user_agent: Optional[str] = Field(None, alias="userAgent") + user_agent: str | None = Field(None, alias="userAgent") class APIGatewayWebSocketEventRequestContextBase(BaseModel): @@ -61,4 +61,4 @@ class APIGatewayWebSocketDisconnectEventModel(BaseModel): class APIGatewayWebSocketMessageEventModel(BaseModel): request_context: APIGatewayWebSocketMessageEventRequestContext = Field(alias="requestContext") is_base64_encoded: bool = Field(alias="isBase64Encoded") - body: Optional[Union[str, Type[BaseModel]]] = Field(None, alias="body") + body: Union[str, Type[BaseModel]] | None = Field(None, alias="body") diff --git a/aws_lambda_powertools/utilities/parser/models/apigwv2.py b/aws_lambda_powertools/utilities/parser/models/apigwv2.py index 9bd66b7a585..b01cb1beb03 100644 --- a/aws_lambda_powertools/utilities/parser/models/apigwv2.py +++ b/aws_lambda_powertools/utilities/parser/models/apigwv2.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import Any, Dict, List, Literal, Optional, Type, Union +from typing import Any, Dict, List, Literal, Type, Union from pydantic import BaseModel, Field, field_validator from pydantic.networks import IPvAnyNetwork @@ -14,24 +14,24 @@ class RequestContextV2AuthorizerIamCognito(BaseModel): class RequestContextV2AuthorizerIam(BaseModel): - accessKey: Optional[str] = None - accountId: Optional[str] = None - callerId: Optional[str] = None - principalOrgId: Optional[str] = None - userArn: Optional[str] = None - userId: Optional[str] = None - cognitoIdentity: Optional[RequestContextV2AuthorizerIamCognito] = None + accessKey: str | None = None + accountId: str | None = None + callerId: str | None = None + principalOrgId: str | None = None + userArn: str | None = None + userId: str | None = None + cognitoIdentity: RequestContextV2AuthorizerIamCognito | None = None class RequestContextV2AuthorizerJwt(BaseModel): claims: Dict[str, Any] - scopes: Optional[List[str]] = None + scopes: List[str] | None = None class RequestContextV2Authorizer(BaseModel): - jwt: Optional[RequestContextV2AuthorizerJwt] = None - iam: Optional[RequestContextV2AuthorizerIam] = None - lambda_value: Optional[Dict[str, Any]] = Field(None, alias="lambda") + jwt: RequestContextV2AuthorizerJwt | None = None + iam: RequestContextV2AuthorizerIam | None = None + lambda_value: Dict[str, Any] | None = Field(None, alias="lambda") class RequestContextV2Http(BaseModel): @@ -50,7 +50,7 @@ def _validate_source_ip(cls, value): class RequestContextV2(BaseModel): accountId: str apiId: str - authorizer: Optional[RequestContextV2Authorizer] = None + authorizer: RequestContextV2Authorizer | None = None domainName: str domainPrefix: str requestId: str @@ -66,17 +66,17 @@ class APIGatewayProxyEventV2Model(BaseModel): routeKey: str rawPath: str rawQueryString: str - cookies: Optional[List[str]] = None + cookies: List[str] | None = None headers: Dict[str, str] - queryStringParameters: Optional[Dict[str, str]] = None - pathParameters: Optional[Dict[str, str]] = None - stageVariables: Optional[Dict[str, str]] = None + queryStringParameters: Dict[str, str] | None = None + pathParameters: Dict[str, str] | None = None + stageVariables: Dict[str, str] | None = None requestContext: RequestContextV2 - body: Optional[Union[str, Type[BaseModel]]] = None - isBase64Encoded: Optional[bool] = None + body: Union[str, Type[BaseModel]] | None = None + isBase64Encoded: bool | None = None class ApiGatewayAuthorizerRequestV2(APIGatewayProxyEventV2Model): type: Literal["REQUEST"] routeArn: str - identitySource: Optional[List[str]] = None + identitySource: List[str] | None = None diff --git a/aws_lambda_powertools/utilities/parser/models/appsync.py b/aws_lambda_powertools/utilities/parser/models/appsync.py index 6d6deedcdcc..e9fe251d38f 100644 --- a/aws_lambda_powertools/utilities/parser/models/appsync.py +++ b/aws_lambda_powertools/utilities/parser/models/appsync.py @@ -1,16 +1,16 @@ -from typing import Any, Dict, List, Optional, Union +from typing import Any, Dict, List, Union from pydantic import BaseModel, Field class AppSyncIamIdentity(BaseModel): accountId: str = Field(description="The AWS account ID of the caller.", examples=["123456789012"]) - cognitoIdentityPoolId: Optional[str] = Field( + cognitoIdentityPoolId: str | None = Field( default=None, description="The Amazon Cognito identity pool ID associated with the caller.", examples=["us-east-1:12345678-1234-1234-1234-123456789012"], ) - cognitoIdentityId: Optional[str] = Field( + cognitoIdentityId: str | None = Field( default=None, description="The Amazon Cognito identity ID of the caller.", examples=["us-east-1:12345678-1234-1234-1234-123456789012"], @@ -29,12 +29,12 @@ class AppSyncIamIdentity(BaseModel): description="The Amazon Resource Name (ARN) of the IAM user.", examples=["arn:aws:iam::123456789012:user/appsync", "arn:aws:iam::123456789012:user/service-user"], ) - cognitoIdentityAuthType: Optional[str] = Field( + cognitoIdentityAuthType: str | None = Field( default=None, description="Either authenticated or unauthenticated based on the identity type.", examples=["authenticated", "unauthenticated"], ) - cognitoIdentityAuthProvider: Optional[str] = Field( + cognitoIdentityAuthProvider: str | None = Field( default=None, description=( "A comma-separated list of external identity provider information " @@ -74,7 +74,7 @@ class AppSyncCognitoIdentity(BaseModel): description="The default authorization strategy for this caller (ALLOW or DENY).", examples=["ALLOW", "DENY"], ) - groups: Optional[List[str]] = Field( + groups: List[str] | None = Field( default=None, description="The Cognito User Pool groups that the user belongs to.", examples=[["admin", "users"], ["developers"]], @@ -115,7 +115,7 @@ class AppSyncLambdaIdentity(BaseModel): class AppSyncRequestModel(BaseModel): - domainName: Optional[str] = Field( + domainName: str | None = Field( default=None, description=( "The custom domain name used to access the GraphQL endpoint. " @@ -190,11 +190,11 @@ class AppSyncResolverEventModel(BaseModel): {"page": 2, "size": 1, "name": "value"}, ], ) - identity: Optional[AppSyncIdentity] = Field( + identity: AppSyncIdentity | None = Field( default=None, description="Information about the caller identity (authenticated user or API key).", ) - source: Optional[Dict[str, Any]] = Field( + source: Dict[str, Any] | None = Field( default=None, description="The parent object for the field. For top-level fields, this will be null.", examples=[ @@ -208,7 +208,7 @@ class AppSyncResolverEventModel(BaseModel): info: AppSyncInfoModel = Field( description="Information about the GraphQL request including selection set and field details.", ) - prev: Optional[AppSyncPrevModel] = Field( + prev: AppSyncPrevModel | None = Field( default=None, description="Results from the previous resolver in a pipeline resolver.", ) diff --git a/aws_lambda_powertools/utilities/parser/models/appsync_events.py b/aws_lambda_powertools/utilities/parser/models/appsync_events.py index ceeb3ae621a..a1168d5dd3f 100644 --- a/aws_lambda_powertools/utilities/parser/models/appsync_events.py +++ b/aws_lambda_powertools/utilities/parser/models/appsync_events.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Literal, Optional +from typing import Any, Dict, List, Literal from pydantic import BaseModel, Field @@ -51,7 +51,7 @@ class AppSyncEventsEventModel(BaseModel): class AppSyncEventsModel(BaseModel): - identity: Optional[AppSyncIdentity] = Field( + identity: AppSyncIdentity | None = Field( default=None, description="Information about the caller identity (authenticated user or API key).", ) @@ -59,17 +59,17 @@ class AppSyncEventsModel(BaseModel): info: AppSyncEventsInfoModel = Field( description="Information about the AppSync Events operation including channel details.", ) - prev: Optional[str] = Field( + prev: str | None = Field( default=None, description="Results from the previous operation in a pipeline resolver.", examples=["previous-result-data"], ) - outErrors: Optional[List[str]] = Field( + outErrors: List[str] | None = Field( default=None, description="List of output errors that occurred during event processing.", examples=[["Error message 1", "Error message 2"]], ) - stash: Optional[Dict[str, Any]] = Field( + stash: Dict[str, Any] | None = Field( default=None, description=( "The stash is a map that is made available inside each resolver and function mapping template. " @@ -77,7 +77,7 @@ class AppSyncEventsModel(BaseModel): ), examples=[{"customData": "value", "userId": "123"}], ) - events: Optional[List[AppSyncEventsEventModel]] = Field( + events: List[AppSyncEventsEventModel] | None = Field( default=None, description="List of events being published or subscribed to in the AppSync Events operation.", examples=[ diff --git a/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py b/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py index 1aa5ae07a34..c06cfd457b6 100644 --- a/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py +++ b/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional +from typing import Dict, List from pydantic import BaseModel, Field @@ -34,8 +34,8 @@ class BedrockAgentEventModel(BaseModel): session_attributes: Dict[str, str] = Field({}, alias="sessionAttributes") prompt_session_attributes: Dict[str, str] = Field({}, alias="promptSessionAttributes") agent: BedrockAgentModel - parameters: Optional[List[BedrockAgentPropertyModel]] = None - request_body: Optional[BedrockAgentRequestBodyModel] = Field(None, alias="requestBody") + parameters: List[BedrockAgentPropertyModel] | None = None + request_body: BedrockAgentRequestBodyModel | None = Field(None, alias="requestBody") class BedrockAgentFunctionEventModel(BaseModel): @@ -51,6 +51,6 @@ class BedrockAgentFunctionEventModel(BaseModel): session_id: str = Field(..., alias="sessionId") action_group: str = Field(..., alias="actionGroup") function: str - parameters: Optional[List[BedrockAgentPropertyModel]] = None + parameters: List[BedrockAgentPropertyModel] | None = None session_attributes: Dict[str, str] = Field({}, alias="sessionAttributes") prompt_session_attributes: Dict[str, str] = Field({}, alias="promptSessionAttributes") diff --git a/aws_lambda_powertools/utilities/parser/models/cloudwatch.py b/aws_lambda_powertools/utilities/parser/models/cloudwatch.py index 6c3d25e1727..0fdc7562962 100644 --- a/aws_lambda_powertools/utilities/parser/models/cloudwatch.py +++ b/aws_lambda_powertools/utilities/parser/models/cloudwatch.py @@ -3,7 +3,7 @@ import logging import zlib from datetime import datetime -from typing import List, Optional, Type, Union +from typing import List, Type, Union from pydantic import BaseModel, Field, field_validator @@ -47,7 +47,7 @@ class CloudWatchLogsDecode(BaseModel): description="Array of log events included in the message.", examples=[[{"id": "eventId1", "timestamp": 1673779200000, "message": "Sample log line"}]], ) - policyLevel: Optional[str] = Field( + policyLevel: str | None = Field( default=None, description="Optional field specifying the policy level applied to the subscription filter, if present.", examples=["ACCOUNT", "LOG_GROUP"], diff --git a/aws_lambda_powertools/utilities/parser/models/cognito.py b/aws_lambda_powertools/utilities/parser/models/cognito.py index 05726e37db4..75a21254324 100644 --- a/aws_lambda_powertools/utilities/parser/models/cognito.py +++ b/aws_lambda_powertools/utilities/parser/models/cognito.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Literal, Optional +from typing import Any, Dict, List, Literal from pydantic import BaseModel @@ -14,22 +14,22 @@ class CognitoTriggerBaseSchema(BaseModel): version: str region: str userPoolId: str - userName: Optional[str] = None + userName: str | None = None callerContext: CognitoCallerContextModel # Models for Pre-Signup flow class CognitoPreSignupRequestModel(BaseModel): userAttributes: Dict[str, Any] - validationData: Optional[Dict[str, Any]] = None - clientMetadata: Optional[Dict[str, Any]] = None - userNotFound: Optional[bool] = None + validationData: Dict[str, Any] | None = None + clientMetadata: Dict[str, Any] | None = None + userNotFound: bool | None = None class CognitoPreSignupResponseModel(BaseModel): - autoConfirmUser: Optional[bool] = False - autoVerifyPhone: Optional[bool] = False - autoVerifyEmail: Optional[bool] = False + autoConfirmUser: bool | None = False + autoVerifyPhone: bool | None = False + autoVerifyEmail: bool | None = False class CognitoPreSignupTriggerModel(CognitoTriggerBaseSchema): @@ -41,7 +41,7 @@ class CognitoPreSignupTriggerModel(CognitoTriggerBaseSchema): # Models for Post-Confirmation flow class CognitoPostConfirmationRequestModel(BaseModel): userAttributes: Dict[str, Any] - clientMetadata: Optional[Dict[str, Any]] = None + clientMetadata: Dict[str, Any] | None = None class CognitoPostConfirmationTriggerModel(CognitoTriggerBaseSchema): @@ -53,8 +53,8 @@ class CognitoPostConfirmationTriggerModel(CognitoTriggerBaseSchema): # Models for Pre-Authentication flow class CognitoPreAuthenticationRequestModel(BaseModel): userAttributes: Dict[str, Any] - validationData: Optional[Dict[str, Any]] = None - userNotFound: Optional[bool] = None + validationData: Dict[str, Any] | None = None + userNotFound: bool | None = None class CognitoPreAuthenticationTriggerModel(CognitoTriggerBaseSchema): @@ -66,8 +66,8 @@ class CognitoPreAuthenticationTriggerModel(CognitoTriggerBaseSchema): # Models for Post-Authentication flow class CognitoPostAuthenticationRequestModel(BaseModel): userAttributes: Dict[str, Any] - newDeviceUsed: Optional[bool] = None - clientMetadata: Optional[Dict[str, Any]] = None + newDeviceUsed: bool | None = None + clientMetadata: Dict[str, Any] | None = None class CognitoPostAuthenticationTriggerModel(CognitoTriggerBaseSchema): @@ -80,13 +80,13 @@ class CognitoPostAuthenticationTriggerModel(CognitoTriggerBaseSchema): class CognitoGroupConfigurationModel(BaseModel): groupsToOverride: List[str] iamRolesToOverride: List[str] - preferredRole: Optional[str] = None + preferredRole: str | None = None class CognitoPreTokenGenerationRequestModel(BaseModel): userAttributes: Dict[str, Any] groupConfiguration: CognitoGroupConfigurationModel - clientMetadata: Optional[Dict[str, Any]] = None + clientMetadata: Dict[str, Any] | None = None class CognitoPreTokenGenerationTriggerModelV1(CognitoTriggerBaseSchema): @@ -96,7 +96,7 @@ class CognitoPreTokenGenerationTriggerModelV1(CognitoTriggerBaseSchema): class CognitoPreTokenGenerationRequestModelV2AndV3(CognitoPreTokenGenerationRequestModel): - scopes: Optional[Dict[str, Any]] = None + scopes: Dict[str, Any] | None = None class CognitoPreTokenGenerationTriggerModelV2AndV3(CognitoTriggerBaseSchema): @@ -107,17 +107,17 @@ class CognitoPreTokenGenerationTriggerModelV2AndV3(CognitoTriggerBaseSchema): # Models for User Migration flow class CognitoMigrateUserRequestModel(BaseModel): password: str - validationData: Optional[Dict[str, Any]] = None - clientMetadata: Optional[Dict[str, Any]] = None + validationData: Dict[str, Any] | None = None + clientMetadata: Dict[str, Any] | None = None class CognitoMigrateUserResponseModel(BaseModel): - userAttributes: Optional[Dict[str, Any]] = None - finalUserStatus: Optional[str] = None - messageAction: Optional[str] = None - desiredDeliveryMediums: Optional[List[str]] = None - forceAliasCreation: Optional[bool] = None - enableSMSMFA: Optional[bool] = None + userAttributes: Dict[str, Any] | None = None + finalUserStatus: str | None = None + messageAction: str | None = None + desiredDeliveryMediums: List[str] | None = None + forceAliasCreation: bool | None = None + enableSMSMFA: bool | None = None class CognitoMigrateUserTriggerModel(CognitoTriggerBaseSchema): @@ -131,15 +131,15 @@ class CognitoMigrateUserTriggerModel(CognitoTriggerBaseSchema): class CognitoCustomMessageRequestModel(BaseModel): userAttributes: Dict[str, Any] codeParameter: str - linkParameter: Optional[str] = None - usernameParameter: Optional[str] = None - clientMetadata: Optional[Dict[str, Any]] = None + linkParameter: str | None = None + usernameParameter: str | None = None + clientMetadata: Dict[str, Any] | None = None class CognitoCustomMessageResponseModel(BaseModel): - smsMessage: Optional[str] = None - emailMessage: Optional[str] = None - emailSubject: Optional[str] = None + smsMessage: str | None = None + emailMessage: str | None = None + emailSubject: str | None = None class CognitoCustomMessageTriggerModel(CognitoTriggerBaseSchema): @@ -152,7 +152,7 @@ class CognitoCustomMessageTriggerModel(CognitoTriggerBaseSchema): class CognitoCustomEmailSMSSenderRequestModel(BaseModel): type: str code: str - clientMetadata: Optional[Dict[str, Any]] = None + clientMetadata: Dict[str, Any] | None = None userAttributes: Dict[str, Any] @@ -179,20 +179,20 @@ class CognitoChallengeResultModel(BaseModel): "ADMIN_NO_SRP_AUTH", ] challengeResult: bool - challengeMetadata: Optional[str] = None + challengeMetadata: str | None = None class CognitoAuthChallengeRequestModel(BaseModel): userAttributes: Dict[str, Any] session: List[CognitoChallengeResultModel] - clientMetadata: Optional[Dict[str, Any]] = None - userNotFound: Optional[bool] = None + clientMetadata: Dict[str, Any] | None = None + userNotFound: bool | None = None class CognitoDefineAuthChallengeResponseModel(BaseModel): - challengeName: Optional[str] = None - issueTokens: Optional[bool] = None - failAuthentication: Optional[bool] = None + challengeName: str | None = None + issueTokens: bool | None = None + failAuthentication: bool | None = None class CognitoDefineAuthChallengeTriggerModel(CognitoTriggerBaseSchema): @@ -202,9 +202,9 @@ class CognitoDefineAuthChallengeTriggerModel(CognitoTriggerBaseSchema): class CognitoCreateAuthChallengeResponseModel(BaseModel): - publicChallengeParameters: Optional[Dict[str, Any]] = None - privateChallengeParameters: Optional[Dict[str, Any]] = None - challengeMetadata: Optional[str] = None + publicChallengeParameters: Dict[str, Any] | None = None + privateChallengeParameters: Dict[str, Any] | None = None + challengeMetadata: str | None = None class CognitoCreateAuthChallengeTriggerModel(CognitoTriggerBaseSchema): @@ -217,8 +217,8 @@ class CognitoVerifyAuthChallengeRequestModel(BaseModel): userAttributes: Dict[str, Any] privateChallengeParameters: Dict[str, Any] challengeAnswer: str - clientMetadata: Optional[Dict[str, Any]] = None - userNotFound: Optional[bool] = None + clientMetadata: Dict[str, Any] | None = None + userNotFound: bool | None = None class CognitoVerifyAuthChallengeResponseModel(BaseModel): diff --git a/aws_lambda_powertools/utilities/parser/models/dynamodb.py b/aws_lambda_powertools/utilities/parser/models/dynamodb.py index 595e19068e3..714cb06e90a 100644 --- a/aws_lambda_powertools/utilities/parser/models/dynamodb.py +++ b/aws_lambda_powertools/utilities/parser/models/dynamodb.py @@ -1,6 +1,6 @@ # ruff: noqa: FA100 from datetime import datetime -from typing import Any, Dict, List, Literal, Optional, Type, Union +from typing import Any, Dict, List, Literal, Type, Union from pydantic import BaseModel, ConfigDict, Field, field_validator from pydantic.alias_generators import to_camel @@ -11,18 +11,18 @@ class DynamoDBStreamChangedRecordModel(BaseModel): - ApproximateCreationDateTime: Optional[datetime] = Field( # AWS sends this as Unix epoch float + ApproximateCreationDateTime: datetime | None = Field( # AWS sends this as Unix epoch float default=None, description="The approximate date and time when the stream record was created (Unix epoch time).", examples=[1693997155.0], ) Keys: Dict[str, Any] = Field(description="Primary key attributes for the item.", examples=[{"Id": {"N": "101"}}]) - NewImage: Optional[Union[Dict[str, Any], Type[BaseModel], BaseModel]] = Field( + NewImage: Union[Dict[str, Any], Type[BaseModel], BaseModel] | None = Field( default=None, description="The item after modifications, in DynamoDB attribute-value format.", examples=[{"Message": {"S": "New item!"}, "Id": {"N": "101"}}], ) - OldImage: Optional[Union[Dict[str, Any], Type[BaseModel], BaseModel]] = Field( + OldImage: Union[Dict[str, Any], Type[BaseModel], BaseModel] | None = Field( default=None, description="The item before modifications, in DynamoDB attribute-value format.", examples=[{"Message": {"S": "Old item!"}, "Id": {"N": "100"}}], @@ -80,7 +80,7 @@ class DynamoDBStreamRecordModel(BaseModel): }, ], ) - userIdentity: Optional[UserIdentity] = Field( + userIdentity: UserIdentity | None = Field( default=None, description="Information about the identity that made the request.", examples=[{"type": "Service", "principalId": "dynamodb.amazonaws.com"}], @@ -175,7 +175,7 @@ class ResponseContext(BaseModel): description="The version of the Lambda executed", examples=["$LATEST"], ) - function_error: Optional[str] = Field( + function_error: str | None = Field( default=None, description="", examples=["Unhandled"], diff --git a/aws_lambda_powertools/utilities/parser/models/event_bridge.py b/aws_lambda_powertools/utilities/parser/models/event_bridge.py index 67eef21dbf2..11c2e28bc41 100644 --- a/aws_lambda_powertools/utilities/parser/models/event_bridge.py +++ b/aws_lambda_powertools/utilities/parser/models/event_bridge.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import List, Optional +from typing import List from pydantic import BaseModel, ConfigDict, Field, field_validator @@ -50,7 +50,7 @@ class EventBridgeModel(BaseModel): detail: RawDictOrModel = Field( description="A JSON object, whose content is at the discretion of the service originating the event.", ) - replay_name: Optional[str] = Field( + replay_name: str | None = Field( None, alias="replay-name", description="Identifies whether the event is being replayed and what is the name of the replay.", diff --git a/aws_lambda_powertools/utilities/parser/models/iot_registry_events.py b/aws_lambda_powertools/utilities/parser/models/iot_registry_events.py index 7af5992a20d..950aa01fe53 100644 --- a/aws_lambda_powertools/utilities/parser/models/iot_registry_events.py +++ b/aws_lambda_powertools/utilities/parser/models/iot_registry_events.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import Any, Dict, List, Literal, Optional +from typing import Any, Dict, List, Literal from pydantic import BaseModel, Field @@ -25,7 +25,7 @@ class IoTCoreThingEvent(IoTCoreRegistryEventsBase): account_id: str = Field(..., alias="accountId") thing_name: str = Field(..., alias="thingName") version_number: int = Field(..., alias="versionNumber") - thing_type_name: Optional[str] = Field(None, alias="thingTypeName") + thing_type_name: str | None = Field(None, alias="thingTypeName") attributes: Dict[str, Any] @@ -46,7 +46,7 @@ class IoTCoreThingTypeEvent(IoTCoreRegistryEventsBase): thing_type_id: str = Field(..., alias="thingTypeId") thing_type_name: str = Field(..., alias="thingTypeName") is_deprecated: bool = Field(..., alias="isDeprecated") - deprecation_date: Optional[datetime] = Field(None, alias="deprecationDate") + deprecation_date: datetime | None = Field(None, alias="deprecationDate") searchable_attributes: List[str] = Field(..., alias="searchableAttributes") propagating_attributes: List[Dict[str, str]] = Field(..., alias="propagatingAttributes") description: str @@ -84,12 +84,12 @@ class IoTCoreThingGroupEvent(IoTCoreRegistryEventsBase): thing_group_id: str = Field(..., alias="thingGroupId") thing_group_name: str = Field(..., alias="thingGroupName") version_number: int = Field(..., alias="versionNumber") - parent_group_name: Optional[str] = Field(None, alias="parentGroupName") - parent_group_id: Optional[str] = Field(None, alias="parentGroupId") + parent_group_name: str | None = Field(None, alias="parentGroupName") + parent_group_id: str | None = Field(None, alias="parentGroupId") description: str root_to_parent_thing_groups: List[Dict[str, str]] = Field(..., alias="rootToParentThingGroups") attributes: Dict[str, Any] - dynamic_group_mapping_id: Optional[str] = Field(None, alias="dynamicGroupMappingId") + dynamic_group_mapping_id: str | None = Field(None, alias="dynamicGroupMappingId") class IoTCoreAddOrRemoveFromThingGroupEvent(IoTCoreRegistryEventsBase): diff --git a/aws_lambda_powertools/utilities/parser/models/kafka.py b/aws_lambda_powertools/utilities/parser/models/kafka.py index df232469b95..9ce0063d09b 100644 --- a/aws_lambda_powertools/utilities/parser/models/kafka.py +++ b/aws_lambda_powertools/utilities/parser/models/kafka.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import Dict, List, Literal, Optional, Type, Union +from typing import Dict, List, Literal, Type, Union from pydantic import BaseModel, Field, field_validator @@ -40,7 +40,7 @@ class KafkaRecordModel(BaseModel): description="The type of timestamp (CREATE_TIME or LOG_APPEND_TIME).", examples=["CREATE_TIME", "LOG_APPEND_TIME"], ) - key: Optional[bytes] = Field( + key: bytes | None = Field( default=None, description="The message key, base64-encoded. Can be null for messages without keys.", examples=["cmVjb3JkS2V5", "dXNlci0xMjM=", "b3JkZXItNDU2", None], @@ -61,12 +61,12 @@ class KafkaRecordModel(BaseModel): [], ], ) - keySchemaMetadata: Optional[KafkaRecordSchemaMetadata] = Field( + keySchemaMetadata: KafkaRecordSchemaMetadata | None = Field( default=None, description="Schema metadata for the message key when using schema registry.", examples=[{"dataFormat": "AVRO", "schemaId": "1234"}, None], ) - valueSchemaMetadata: Optional[KafkaRecordSchemaMetadata] = Field( + valueSchemaMetadata: KafkaRecordSchemaMetadata | None = Field( default=None, description="Schema metadata for the message value when using schema registry.", examples=[{"dataFormat": "AVRO", "schemaId": "1234"}, None], diff --git a/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py b/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py index 697a3fbdd89..77e7b47baa6 100644 --- a/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py +++ b/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py @@ -1,4 +1,4 @@ -from typing import List, Optional, Type, Union +from typing import List, Type, Union from pydantic import BaseModel, Field, PositiveInt, field_validator @@ -45,7 +45,7 @@ class KinesisFirehoseRecord(BaseModel): (Unix timestamp in milliseconds).", examples=[1428537600000, 1609459200500], ) - kinesisRecordMetadata: Optional[KinesisFirehoseRecordMetadata] = Field( + kinesisRecordMetadata: KinesisFirehoseRecordMetadata | None = Field( None, description="Metadata about the original Kinesis stream record \ (only present when the delivery stream source is a Kinesis stream).", @@ -69,7 +69,7 @@ class KinesisFirehoseModel(BaseModel): description="The AWS region where the delivery stream is located.", examples=["us-east-1", "us-west-2", "eu-west-1"], ) - sourceKinesisStreamArn: Optional[str] = Field( + sourceKinesisStreamArn: str | None = Field( None, description="The ARN of the source Kinesis stream \ (only present when the delivery stream source is a Kinesis stream).", diff --git a/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py b/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py index b9032a4c934..ecad8b26fc7 100644 --- a/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py +++ b/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py @@ -1,5 +1,5 @@ import json -from typing import List, Optional +from typing import List from pydantic import BaseModel, Field, PositiveInt, field_validator @@ -20,7 +20,7 @@ class KinesisFirehoseSqsRecord(BaseModel): (Unix timestamp in milliseconds).", examples=[1428537600000, 1609459200500], ) - kinesisRecordMetadata: Optional[KinesisFirehoseRecordMetadata] = Field( + kinesisRecordMetadata: KinesisFirehoseRecordMetadata | None = Field( None, description="Metadata about the original Kinesis stream record \ (only present when the delivery stream source is a Kinesis stream).", @@ -45,7 +45,7 @@ class KinesisFirehoseSqsModel(BaseModel): description="The AWS region where the delivery stream is located.", examples=["us-east-1", "us-west-2", "eu-west-1"], ) - sourceKinesisStreamArn: Optional[str] = Field( + sourceKinesisStreamArn: str | None = Field( None, description="The ARN of the source Kinesis stream \ (only present when the delivery stream source is a Kinesis stream).", diff --git a/aws_lambda_powertools/utilities/parser/models/s3.py b/aws_lambda_powertools/utilities/parser/models/s3.py index d53a0fe5655..a2aeb945e9e 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3.py +++ b/aws_lambda_powertools/utilities/parser/models/s3.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import List, Literal, Optional, Union +from typing import List, Literal, Union from pydantic import BaseModel, model_validator from pydantic.fields import Field @@ -130,12 +130,12 @@ class S3Object(BaseModel): "logs/2023/01/15/app.log", ], ) - size: Optional[NonNegativeFloat] = Field( + size: NonNegativeFloat | None = Field( default=None, description="The size of the object in bytes.", examples=[1024, 2048576, 0], ) - eTag: Optional[str] = Field( + eTag: str | None = Field( default=None, description="The entity tag (ETag) of the object.", examples=[ @@ -143,7 +143,7 @@ class S3Object(BaseModel): "098f6bcd4621d373cade4e832627b4f6", ], ) - sequencer: Optional[str] = Field( + sequencer: str | None = Field( default=None, description="A string representation of a hexadecimal value used to determine event sequence.", examples=[ @@ -151,7 +151,7 @@ class S3Object(BaseModel): "005B21C13A6F24045E", ], ) - versionId: Optional[str] = Field( + versionId: str | None = Field( default=None, description="The version ID of the object (if versioning is enabled).", examples=[ @@ -188,7 +188,7 @@ class S3Message(BaseModel): }, ], ) - object: Optional[S3Object] = Field( + object: S3Object | None = Field( default=None, description="The S3 object object. Used by most S3 event types.", examples=[ @@ -200,7 +200,7 @@ class S3Message(BaseModel): }, ], ) # noqa: A003 - get_object: Optional[S3Object] = Field( + get_object: S3Object | None = Field( default=None, alias="get_object", description="The S3 object object. Used by IntelligentTiering events instead of 'object'.", @@ -225,7 +225,7 @@ class S3EventNotificationObjectModel(BaseModel): "logs/2023/01/15/app.log", ], ) - size: Optional[NonNegativeFloat] = Field( + size: NonNegativeFloat | None = Field( default=None, description="The size of the object in bytes.", examples=[1024, 2048576, 0], @@ -238,7 +238,7 @@ class S3EventNotificationObjectModel(BaseModel): "098f6bcd4621d373cade4e832627b4f6", ], ) - version_id: Optional[str] = Field( + version_id: str | None = Field( default=None, alias="version-id", description="The version ID of the object (if versioning is enabled).", @@ -247,7 +247,7 @@ class S3EventNotificationObjectModel(BaseModel): "null", ], ) - sequencer: Optional[str] = Field( + sequencer: str | None = Field( default=None, description="A string representation of a hexadecimal value used to determine event sequence.", examples=[ @@ -307,7 +307,7 @@ class S3EventNotificationEventBridgeDetailModel(BaseModel): "123456789012", ], ) - source_ip_address: Optional[str] = Field( + source_ip_address: str | None = Field( None, alias="source-ip-address", description="Source IP address of S3 request. Only present for events triggered by an S3 request.", @@ -315,7 +315,7 @@ class S3EventNotificationEventBridgeDetailModel(BaseModel): "255.255.255.255", ], ) - reason: Optional[str] = Field( + reason: str | None = Field( default=None, description="For 'Object Created' events, the S3 API used to create the object: PutObject, POST Object, " "CopyObject, or CompleteMultipartUpload. For 'Object Deleted' events, this is set to 'DeleteObject' " @@ -327,7 +327,7 @@ class S3EventNotificationEventBridgeDetailModel(BaseModel): "DeleteObject", ], ) - deletion_type: Optional[str] = Field( + deletion_type: str | None = Field( default=None, alias="deletion-type", description="For 'Object Deleted' events, when an unversioned object is deleted, or a versioned object is " @@ -336,28 +336,28 @@ class S3EventNotificationEventBridgeDetailModel(BaseModel): "see https://docs.aws.amazon.com/AmazonS3/latest/userguide/DeletingObjectVersions.html", examples=["Delete Marker Created", "Permanently Deleted"], ) - restore_expiry_time: Optional[str] = Field( + restore_expiry_time: str | None = Field( default=None, alias="restore-expiry-time", description="For 'Object Restore Completed' events, the time when the temporary copy of the object will be " "deleted from S3. For more information, see https://docs.aws.amazon.com/AmazonS3/latest/userguide/archived-objects.html.", examples=["2021-11-13T00:00:00Z"], ) - source_storage_class: Optional[str] = Field( + source_storage_class: str | None = Field( default=None, alias="source-storage-class", description="For 'Object Restore Initiated' and 'Object Restore Completed' events, the storage class of the " "object being restored. For more information, see https://docs.aws.amazon.com/AmazonS3/latest/userguide/archived-objects.html.", examples=["GLACIER", "STANDARD", "STANDARD_IA"], ) - destination_storage_class: Optional[str] = Field( + destination_storage_class: str | None = Field( default=None, alias="destination-storage-class", description="For 'Object Storage Class Changed' events, the new storage class of the object. For more " "information, see https://docs.aws.amazon.com/AmazonS3/latest/userguide/lifecycle-transition-general-considerations.html.", examples=["INTELLIGENT_TIERING", "STANDARD", "STANDARD_IA"], ) - destination_access_tier: Optional[str] = Field( + destination_access_tier: str | None = Field( default=None, alias="destination-access-tier", description="For 'Object Access Tier Changed' events, the new access tier of the object. For more information, " @@ -462,7 +462,7 @@ class S3RecordModel(BaseModel): }, ], ) - glacierEventData: Optional[S3EventRecordGlacierEventData] = Field( + glacierEventData: S3EventRecordGlacierEventData | None = Field( default=None, description="The Glacier event data object.", examples=[ @@ -474,7 +474,7 @@ class S3RecordModel(BaseModel): }, ], ) - intelligentTieringEventData: Optional[S3EventRecordIntelligentTieringEventData] = Field( + intelligentTieringEventData: S3EventRecordIntelligentTieringEventData | None = Field( default=None, description="The Intelligent-Tiering event data object.", examples=[ diff --git a/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py b/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py index 934ace9ac07..b9581243f51 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py +++ b/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, List, Literal, Optional +from typing import Any, Dict, List, Literal from pydantic import BaseModel, model_validator @@ -6,9 +6,9 @@ class S3BatchOperationTaskModel(BaseModel): taskId: str s3Key: str - s3VersionId: Optional[str] = None - s3BucketArn: Optional[str] = None - s3Bucket: Optional[str] = None + s3VersionId: str | None = None + s3BucketArn: str | None = None + s3Bucket: str | None = None @model_validator(mode="before") def validate_s3bucket(cls, values: Dict[str, Any]) -> Dict[str, Any]: @@ -20,7 +20,7 @@ def validate_s3bucket(cls, values: Dict[str, Any]) -> Dict[str, Any]: class S3BatchOperationJobModel(BaseModel): id: str - userArguments: Optional[Dict[str, Any]] = None + userArguments: Dict[str, Any] | None = None class S3BatchOperationModel(BaseModel): diff --git a/aws_lambda_powertools/utilities/parser/models/s3_object_event.py b/aws_lambda_powertools/utilities/parser/models/s3_object_event.py index 867cd996fa0..1bd2c2628af 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3_object_event.py +++ b/aws_lambda_powertools/utilities/parser/models/s3_object_event.py @@ -1,4 +1,4 @@ -from typing import Dict, Optional, Type, Union +from typing import Dict, Type, Union from pydantic import BaseModel, HttpUrl @@ -22,7 +22,7 @@ class S3ObjectUserRequest(BaseModel): class S3ObjectSessionIssuer(BaseModel): type: str # noqa: A003, VNE003 - userName: Optional[str] = None + userName: str | None = None principalId: str arn: str accountId: str @@ -42,10 +42,10 @@ class S3ObjectUserIdentity(BaseModel): type: str # noqa: A003 accountId: str accessKeyId: str - userName: Optional[str] = None + userName: str | None = None principalId: str arn: str - sessionContext: Optional[S3ObjectSessionContext] = None + sessionContext: S3ObjectSessionContext | None = None class S3ObjectLambdaEvent(BaseModel): diff --git a/aws_lambda_powertools/utilities/parser/models/ses.py b/aws_lambda_powertools/utilities/parser/models/ses.py index 9a7a9914e6e..833cc557df0 100644 --- a/aws_lambda_powertools/utilities/parser/models/ses.py +++ b/aws_lambda_powertools/utilities/parser/models/ses.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import List, Literal, Optional +from typing import List, Literal from pydantic import BaseModel, Field from pydantic.types import PositiveInt @@ -34,10 +34,10 @@ class SesMailHeaders(BaseModel): class SesMailCommonHeaders(BaseModel): header_from: List[str] = Field(..., alias="from") to: List[str] - cc: Optional[List[str]] = None - bcc: Optional[List[str]] = None - sender: Optional[List[str]] = None - reply_to: Optional[List[str]] = Field(None, alias="reply-to") + cc: List[str] | None = None + bcc: List[str] | None = None + sender: List[str] | None = None + reply_to: List[str] | None = Field(None, alias="reply-to") returnPath: str messageId: str date: str diff --git a/aws_lambda_powertools/utilities/parser/models/sns.py b/aws_lambda_powertools/utilities/parser/models/sns.py index 62b8efc2e17..c2a740dbcbd 100644 --- a/aws_lambda_powertools/utilities/parser/models/sns.py +++ b/aws_lambda_powertools/utilities/parser/models/sns.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import Dict, List, Literal, Optional, Union +from typing import Dict, List, Literal, Union from typing import Type as TypingType from pydantic import BaseModel, Field, model_validator @@ -18,7 +18,7 @@ class SnsMsgAttributeModel(BaseModel): class SnsNotificationModel(BaseModel): - Subject: Optional[str] = Field( + Subject: str | None = Field( default=None, description="The subject parameter provided when the notification was published to the topic.", examples=["TestInvoke", "Alert: System maintenance", "Order Confirmation", None], @@ -48,7 +48,7 @@ class SnsNotificationModel(BaseModel): description="The type of message. For Lambda triggers, this is always 'Notification'.", examples=["Notification"], ) - MessageAttributes: Optional[Dict[str, SnsMsgAttributeModel]] = Field( + MessageAttributes: Dict[str, SnsMsgAttributeModel] | None = Field( default=None, description="User-defined message attributes as key-value pairs with type information.", examples=[ @@ -73,7 +73,7 @@ class SnsNotificationModel(BaseModel): "f3c8d4e2-1a2b-4c5d-9e8f-7g6h5i4j3k2l", ], ) - SigningCertUrl: Optional[HttpUrl] = Field( + SigningCertUrl: HttpUrl | None = Field( default=None, description=( "The URL to the certificate that was used to sign the message. " @@ -85,7 +85,7 @@ class SnsNotificationModel(BaseModel): None, ], ) # NOTE: FIFO opt-in removes attribute - Signature: Optional[str] = Field( + Signature: str | None = Field( default=None, description=( "Base64-encoded SHA1withRSA signature of the message. " @@ -105,7 +105,7 @@ class SnsNotificationModel(BaseModel): "2023-12-25T18:45:30.123Z", ], ) - SignatureVersion: Optional[str] = Field( + SignatureVersion: str | None = Field( default=None, description=( "Version of the Amazon SNS signature used. Not present for FIFO topics with content-based deduplication." diff --git a/aws_lambda_powertools/utilities/parser/models/sqs.py b/aws_lambda_powertools/utilities/parser/models/sqs.py index 06452cd2a8f..020fe2288dc 100644 --- a/aws_lambda_powertools/utilities/parser/models/sqs.py +++ b/aws_lambda_powertools/utilities/parser/models/sqs.py @@ -1,5 +1,5 @@ from datetime import datetime -from typing import Dict, List, Literal, Optional, Sequence, Type, Union +from typing import Dict, List, Literal, Sequence, Type, Union from pydantic import BaseModel, Field @@ -13,12 +13,12 @@ class SqsAttributesModel(BaseModel): description="The time the message was first received from the queue (epoch time in milliseconds).", examples=["1545082649185", "1545082650649", "1713185156612"], ) - MessageDeduplicationId: Optional[str] = Field( + MessageDeduplicationId: str | None = Field( default=None, description="Returns the value provided by the producer that calls the SendMessage action.", examples=["msg-dedup-12345", "unique-msg-abc123", None], ) - MessageGroupId: Optional[str] = Field( + MessageGroupId: str | None = Field( default=None, description="Returns the value provided by the producer that calls the SendMessage action.", examples=["order-processing", "user-123-updates", None], @@ -31,17 +31,17 @@ class SqsAttributesModel(BaseModel): description="The time the message was sent to the queue (epoch time in milliseconds).", examples=["1545082649183", "1545082650636", "1713185156609"], ) - SequenceNumber: Optional[str] = Field( + SequenceNumber: str | None = Field( default=None, description="Returns the value provided by Amazon SQS.", examples=["18849496460467696128", "18849496460467696129", None], ) - AWSTraceHeader: Optional[str] = Field( + AWSTraceHeader: str | None = Field( default=None, description="The AWS X-Ray trace header for request tracing.", examples=["Root=1-5e1b4151-5ac6c58239c1e5b4", None], ) - DeadLetterQueueSourceArn: Optional[str] = Field( + DeadLetterQueueSourceArn: str | None = Field( default=None, description="The ARN of the dead-letter queue from which the message was moved.", examples=["arn:aws:sqs:eu-central-1:123456789012:sqs-redrive-SampleQueue-RNvLCpwGmLi7", None], @@ -49,12 +49,12 @@ class SqsAttributesModel(BaseModel): class SqsMsgAttributeModel(BaseModel): - stringValue: Optional[str] = Field( + stringValue: str | None = Field( default=None, description="The string value of the message attribute.", examples=["100", "active", "user-12345", None], ) - binaryValue: Optional[str] = Field( + binaryValue: str | None = Field( default=None, description="The binary value of the message attribute, base64-encoded.", examples=["base64Str", "SGVsbG8gV29ybGQ=", None], @@ -140,7 +140,7 @@ class SqsRecordModel(BaseModel): "6a204bd89f3c8348afd5c77c717a097a", ], ) - md5OfMessageAttributes: Optional[str] = Field( + md5OfMessageAttributes: str | None = Field( default=None, description="An MD5 digest of the non-URL-encoded message attribute string.", examples=[ diff --git a/aws_lambda_powertools/utilities/parser/models/transfer_family.py b/aws_lambda_powertools/utilities/parser/models/transfer_family.py index be23c29449f..8219cef179b 100644 --- a/aws_lambda_powertools/utilities/parser/models/transfer_family.py +++ b/aws_lambda_powertools/utilities/parser/models/transfer_family.py @@ -1,4 +1,4 @@ -from typing import Literal, Optional +from typing import Literal from pydantic import BaseModel, Field from pydantic.networks import IPvAnyAddress @@ -9,7 +9,7 @@ class TransferFamilyAuthorizer(BaseModel): description="The username of the user attempting to authenticate.", examples=["bobusa", "john.doe", "sftp-user-123", "data-transfer-user"], ) - password: Optional[str] = Field( + password: str | None = Field( default=None, description="The password for authentication.", examples=["", "", None], diff --git a/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py b/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py index cdb75642bd5..9ce8b79dd85 100644 --- a/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py +++ b/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py @@ -1,65 +1,65 @@ from datetime import datetime -from typing import Dict, Optional, Type, Union +from typing import Dict, Type, Union from pydantic import BaseModel, Field, field_validator class VpcLatticeV2RequestContextIdentity(BaseModel): - source_vpc_arn: Optional[str] = Field( + source_vpc_arn: str | None = Field( None, alias="sourceVpcArn", description="The ARN of the VPC from which the request originated.", examples=["arn:aws:ec2:us-east-2:123456789012:vpc/vpc-0b8276c84697e7339"], ) - get_type: Optional[str] = Field( + get_type: str | None = Field( None, alias="type", description="The type of identity making the request.", examples=["AWS_IAM", "NONE"], ) - principal: Optional[str] = Field( + principal: str | None = Field( None, alias="principal", description="The principal ARN of the identity making the request.", examples=["arn:aws:sts::123456789012:assumed-role/example-role/057d00f8b51257ba3c853a0f248943cf"], ) - principal_org_id: Optional[str] = Field( + principal_org_id: str | None = Field( None, alias="principalOrgID", description="The AWS organization ID of the principal.", examples=["o-1234567890"], ) - session_name: Optional[str] = Field( + session_name: str | None = Field( None, alias="sessionName", description="The session name for assumed role sessions.", examples=["057d00f8b51257ba3c853a0f248943cf"], ) - x509_subject_cn: Optional[str] = Field( + x509_subject_cn: str | None = Field( None, alias="X509SubjectCn", description="The X.509 certificate subject common name.", examples=["example.com"], ) - x509_issuer_ou: Optional[str] = Field( + x509_issuer_ou: str | None = Field( None, alias="X509IssuerOu", description="The X.509 certificate issuer organizational unit.", examples=["IT Department"], ) - x509_san_dns: Optional[str] = Field( + x509_san_dns: str | None = Field( None, alias="x509SanDns", description="The X.509 certificate Subject Alternative Name DNS entry.", examples=["example.com"], ) - x509_san_uri: Optional[str] = Field( + x509_san_uri: str | None = Field( None, alias="X509SanUri", description="The X.509 certificate Subject Alternative Name URI entry.", examples=["https://example.com"], ) - x509_san_name_cn: Optional[str] = Field( + x509_san_name_cn: str | None = Field( None, alias="X509SanNameCn", description="The X.509 certificate Subject Alternative Name common name.", @@ -120,17 +120,17 @@ class VpcLatticeV2Model(BaseModel): {"content-type": "application/json"}, ], ) - query_string_parameters: Optional[Dict[str, str]] = Field( + query_string_parameters: Dict[str, str] | None = Field( None, alias="queryStringParameters", description="The query string parameters as key-value pairs.", examples=[{"order-id": "1"}, {"page": "2", "limit": "10"}], ) - body: Optional[Union[str, Type[BaseModel]]] = Field( + body: Union[str, Type[BaseModel]] | None = Field( None, description="The request body. Can be a string or a parsed model if content-type allows parsing.", ) - is_base64_encoded: Optional[bool] = Field( + is_base64_encoded: bool | None = Field( None, alias="isBase64Encoded", description="Indicates whether the body is base64-encoded.", diff --git a/examples/batch_processing/src/advanced_accessing_lambda_context.py b/examples/batch_processing/src/advanced_accessing_lambda_context.py index b0e7eeb98af..d8820138fa1 100644 --- a/examples/batch_processing/src/advanced_accessing_lambda_context.py +++ b/examples/batch_processing/src/advanced_accessing_lambda_context.py @@ -1,5 +1,3 @@ -from typing import Optional - from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.utilities.batch import ( BatchProcessor, @@ -15,7 +13,7 @@ @tracer.capture_method -def record_handler(record: SQSRecord, lambda_context: Optional[LambdaContext] = None): +def record_handler(record: SQSRecord, lambda_context: LambdaContext | None = None): if lambda_context is not None: remaining_time = lambda_context.get_remaining_time_in_millis() logger.info(remaining_time) diff --git a/examples/batch_processing/src/advanced_accessing_lambda_context_manager.py b/examples/batch_processing/src/advanced_accessing_lambda_context_manager.py index 17b719a84d4..11e92a13f93 100644 --- a/examples/batch_processing/src/advanced_accessing_lambda_context_manager.py +++ b/examples/batch_processing/src/advanced_accessing_lambda_context_manager.py @@ -1,5 +1,3 @@ -from typing import Optional - from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.utilities.batch import BatchProcessor, EventType from aws_lambda_powertools.utilities.data_classes.sqs_event import SQSRecord @@ -11,7 +9,7 @@ @tracer.capture_method -def record_handler(record: SQSRecord, lambda_context: Optional[LambdaContext] = None): +def record_handler(record: SQSRecord, lambda_context: LambdaContext | None = None): if lambda_context is not None: remaining_time = lambda_context.get_remaining_time_in_millis() logger.info(remaining_time) diff --git a/examples/batch_processing/src/pydantic_dynamodb.py b/examples/batch_processing/src/pydantic_dynamodb.py index b46f5c78201..7e411a39caa 100644 --- a/examples/batch_processing/src/pydantic_dynamodb.py +++ b/examples/batch_processing/src/pydantic_dynamodb.py @@ -1,5 +1,5 @@ import json -from typing import Dict, Optional +from typing import Dict from typing_extensions import Literal @@ -32,8 +32,8 @@ def transform_message_to_dict(cls, value: Dict[Literal["S"], str]): class OrderDynamoDBChangeRecord(DynamoDBStreamChangedRecordModel): # type: ignore[override] - NewImage: Optional[OrderDynamoDB] - OldImage: Optional[OrderDynamoDB] + NewImage: OrderDynamoDB | None + OldImage: OrderDynamoDB | None class OrderDynamoDBRecord(DynamoDBStreamRecordModel): # type: ignore[override] diff --git a/examples/build_recipes/poetry/app_poetry.py b/examples/build_recipes/poetry/app_poetry.py index d570cca39cf..47927eb25b9 100644 --- a/examples/build_recipes/poetry/app_poetry.py +++ b/examples/build_recipes/poetry/app_poetry.py @@ -1,5 +1,3 @@ -from typing import Optional - from pydantic import BaseModel from aws_lambda_powertools import Logger, Metrics, Tracer @@ -16,7 +14,7 @@ class UserModel(BaseModel): name: str email: str - age: Optional[int] = None + age: int | None = None @app.post("/users") diff --git a/examples/build_recipes/sam/no-layers/src/app_sam_no_layer.py b/examples/build_recipes/sam/no-layers/src/app_sam_no_layer.py index dcda4cede13..04c2d227c73 100644 --- a/examples/build_recipes/sam/no-layers/src/app_sam_no_layer.py +++ b/examples/build_recipes/sam/no-layers/src/app_sam_no_layer.py @@ -1,5 +1,3 @@ -from typing import Optional - from pydantic import BaseModel from aws_lambda_powertools import Logger, Metrics, Tracer @@ -16,7 +14,7 @@ class UserModel(BaseModel): name: str email: str - age: Optional[int] = None + age: int | None = None @app.get("/health") diff --git a/examples/build_recipes/sam/with-layers/src/app/app_sam_layer.py b/examples/build_recipes/sam/with-layers/src/app/app_sam_layer.py index 9d4b39e63a1..56425bce2aa 100644 --- a/examples/build_recipes/sam/with-layers/src/app/app_sam_layer.py +++ b/examples/build_recipes/sam/with-layers/src/app/app_sam_layer.py @@ -1,5 +1,3 @@ -from typing import Optional - import requests from pydantic import BaseModel @@ -17,7 +15,7 @@ class UserModel(BaseModel): name: str email: str - age: Optional[int] = None + age: int | None = None @app.get("/health") diff --git a/examples/event_handler_graphql/src/enable_exceptions_batch_resolver.py b/examples/event_handler_graphql/src/enable_exceptions_batch_resolver.py index 1d94e4693c8..b32399167fa 100644 --- a/examples/event_handler_graphql/src/enable_exceptions_batch_resolver.py +++ b/examples/event_handler_graphql/src/enable_exceptions_batch_resolver.py @@ -1,4 +1,4 @@ -from typing import Dict, Optional +from typing import Dict from aws_lambda_powertools.event_handler import AppSyncResolver from aws_lambda_powertools.utilities.data_classes import AppSyncResolverEvent @@ -18,7 +18,7 @@ class PostRelatedNotFound(Exception): ... @app.batch_resolver(type_name="Query", field_name="relatedPosts", raise_on_error=True) # (1)! -def related_posts(event: AppSyncResolverEvent, post_id: str) -> Optional[Dict]: +def related_posts(event: AppSyncResolverEvent, post_id: str) -> Dict | None: post_found = posts_related.get(post_id, None) if not post_found: diff --git a/examples/event_handler_rest/src/accessing_request_details.py b/examples/event_handler_rest/src/accessing_request_details.py index e9a5d924017..cd6e8b6a56e 100644 --- a/examples/event_handler_rest/src/accessing_request_details.py +++ b/examples/event_handler_rest/src/accessing_request_details.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import List import requests from requests import Response @@ -18,13 +18,13 @@ def get_todos(): todo_id: str = app.current_event.query_string_parameters["id"] # alternatively - _: Optional[str] = app.current_event.query_string_parameters.get("id") + _: str | None = app.current_event.query_string_parameters.get("id") # or multi-value query string parameters; ?category="red"&?category="blue" _: List[str] = app.current_event.multi_value_query_string_parameters["category"] # Payload - _: Optional[str] = app.current_event.body # raw str | None + _: str | None = app.current_event.body # raw str | None endpoint = "https://jsonplaceholder.typicode.com/todos" if todo_id: diff --git a/examples/event_handler_rest/src/customizing_response_validation.py b/examples/event_handler_rest/src/customizing_response_validation.py index 25aa07bf52a..2043c0c9c57 100644 --- a/examples/event_handler_rest/src/customizing_response_validation.py +++ b/examples/event_handler_rest/src/customizing_response_validation.py @@ -1,5 +1,4 @@ from http import HTTPStatus -from typing import Optional import requests from pydantic import BaseModel, Field @@ -19,7 +18,7 @@ class Todo(BaseModel): userId: int - id_: Optional[int] = Field(alias="id", default=None) + id_: int | None = Field(alias="id", default=None) title: str completed: bool diff --git a/examples/event_handler_rest/src/customizing_response_validation_exception.py b/examples/event_handler_rest/src/customizing_response_validation_exception.py index c94ace290d2..871c222151c 100644 --- a/examples/event_handler_rest/src/customizing_response_validation_exception.py +++ b/examples/event_handler_rest/src/customizing_response_validation_exception.py @@ -1,5 +1,4 @@ from http import HTTPStatus -from typing import Optional import requests from pydantic import BaseModel, Field @@ -21,7 +20,7 @@ class Todo(BaseModel): userId: int - id_: Optional[int] = Field(alias="id", default=None) + id_: int | None = Field(alias="id", default=None) title: str completed: bool diff --git a/examples/event_handler_rest/src/data_validation.py b/examples/event_handler_rest/src/data_validation.py index 1daa9fb2174..bbb43df74ea 100644 --- a/examples/event_handler_rest/src/data_validation.py +++ b/examples/event_handler_rest/src/data_validation.py @@ -1,5 +1,3 @@ -from typing import Optional - import requests from pydantic import BaseModel, Field @@ -15,7 +13,7 @@ class Todo(BaseModel): # (2)! userId: int - id_: Optional[int] = Field(alias="id", default=None) + id_: int | None = Field(alias="id", default=None) title: str completed: bool diff --git a/examples/event_handler_rest/src/data_validation_fine_grained_response.py b/examples/event_handler_rest/src/data_validation_fine_grained_response.py index 1209c6a1af1..36ee0a41299 100644 --- a/examples/event_handler_rest/src/data_validation_fine_grained_response.py +++ b/examples/event_handler_rest/src/data_validation_fine_grained_response.py @@ -1,5 +1,4 @@ from http import HTTPStatus -from typing import Optional import requests from pydantic import BaseModel, Field @@ -16,7 +15,7 @@ class Todo(BaseModel): userId: int - id_: Optional[int] = Field(alias="id", default=None) + id_: int | None = Field(alias="id", default=None) title: str completed: bool diff --git a/examples/event_handler_rest/src/data_validation_sanitized_error.py b/examples/event_handler_rest/src/data_validation_sanitized_error.py index 71849938f48..72d8c82b737 100644 --- a/examples/event_handler_rest/src/data_validation_sanitized_error.py +++ b/examples/event_handler_rest/src/data_validation_sanitized_error.py @@ -1,5 +1,3 @@ -from typing import Optional - import requests from pydantic import BaseModel, Field @@ -16,7 +14,7 @@ class Todo(BaseModel): userId: int - id_: Optional[int] = Field(alias="id", default=None) + id_: int | None = Field(alias="id", default=None) title: str completed: bool diff --git a/examples/event_handler_rest/src/skip_validating_query_strings.py b/examples/event_handler_rest/src/skip_validating_query_strings.py index 882769239a1..0cf6628035e 100644 --- a/examples/event_handler_rest/src/skip_validating_query_strings.py +++ b/examples/event_handler_rest/src/skip_validating_query_strings.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import List import requests from pydantic import BaseModel, Field @@ -15,14 +15,14 @@ class Todo(BaseModel): userId: int - id_: Optional[int] = Field(alias="id", default=None) + id_: int | None = Field(alias="id", default=None) title: str completed: bool @app.get("/todos") @tracer.capture_method -def get_todos(completed: Optional[str] = None) -> List[Todo]: # (1)! +def get_todos(completed: str | None = None) -> List[Todo]: # (1)! url = "https://jsonplaceholder.typicode.com/todos" if completed is not None: diff --git a/examples/event_handler_rest/src/validating_headers.py b/examples/event_handler_rest/src/validating_headers.py index f92f0ead463..9c649c11bac 100644 --- a/examples/event_handler_rest/src/validating_headers.py +++ b/examples/event_handler_rest/src/validating_headers.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import List import requests from pydantic import BaseModel, Field @@ -17,7 +17,7 @@ class Todo(BaseModel): userId: int - id_: Optional[int] = Field(alias="id", default=None) + id_: int | None = Field(alias="id", default=None) title: str completed: bool diff --git a/examples/event_handler_rest/src/validating_headers_with_pydantic.py b/examples/event_handler_rest/src/validating_headers_with_pydantic.py index 03f6c56e9fd..821ad566185 100644 --- a/examples/event_handler_rest/src/validating_headers_with_pydantic.py +++ b/examples/event_handler_rest/src/validating_headers_with_pydantic.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, Optional +from typing import Any, Dict from pydantic import BaseModel, Field from typing_extensions import Annotated @@ -16,7 +16,7 @@ class Todo(BaseModel): userId: int - id_: Optional[int] = Field(alias="id", default=None) + id_: int | None = Field(alias="id", default=None) title: str completed: bool diff --git a/examples/event_handler_rest/src/validating_path.py b/examples/event_handler_rest/src/validating_path.py index c5ddbba4f37..f1001a6e18f 100644 --- a/examples/event_handler_rest/src/validating_path.py +++ b/examples/event_handler_rest/src/validating_path.py @@ -1,5 +1,3 @@ -from typing import Optional - import requests from pydantic import BaseModel, Field from typing_extensions import Annotated @@ -17,7 +15,7 @@ class Todo(BaseModel): userId: int - id_: Optional[int] = Field(alias="id", default=None) + id_: int | None = Field(alias="id", default=None) title: str completed: bool diff --git a/examples/event_handler_rest/src/validating_payload_subset.py b/examples/event_handler_rest/src/validating_payload_subset.py index ebd0cf0c20f..051505369f9 100644 --- a/examples/event_handler_rest/src/validating_payload_subset.py +++ b/examples/event_handler_rest/src/validating_payload_subset.py @@ -1,5 +1,3 @@ -from typing import Optional - import requests from pydantic import BaseModel, Field from typing_extensions import Annotated @@ -13,7 +11,7 @@ class Todo(BaseModel): userId: int - id_: Optional[int] = Field(alias="id", default=None) + id_: int | None = Field(alias="id", default=None) title: str completed: bool diff --git a/examples/event_handler_rest/src/validating_payloads.py b/examples/event_handler_rest/src/validating_payloads.py index 945cefd8089..a7ed6c88749 100644 --- a/examples/event_handler_rest/src/validating_payloads.py +++ b/examples/event_handler_rest/src/validating_payloads.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import List import requests from pydantic import BaseModel, Field @@ -15,7 +15,7 @@ class Todo(BaseModel): # (2)! userId: int - id_: Optional[int] = Field(alias="id", default=None) + id_: int | None = Field(alias="id", default=None) title: str completed: bool diff --git a/examples/event_handler_rest/src/validating_query_string_with_pydantic.py b/examples/event_handler_rest/src/validating_query_string_with_pydantic.py index 75f6212e1a6..2ea42995c37 100644 --- a/examples/event_handler_rest/src/validating_query_string_with_pydantic.py +++ b/examples/event_handler_rest/src/validating_query_string_with_pydantic.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, Optional +from typing import Any, Dict from pydantic import BaseModel, Field from typing_extensions import Annotated @@ -16,7 +16,7 @@ class Todo(BaseModel): userId: int - id_: Optional[int] = Field(alias="id", default=None) + id_: int | None = Field(alias="id", default=None) title: str completed: bool diff --git a/examples/event_handler_rest/src/validating_query_strings.py b/examples/event_handler_rest/src/validating_query_strings.py index 047e9973b63..75ff7450a1c 100644 --- a/examples/event_handler_rest/src/validating_query_strings.py +++ b/examples/event_handler_rest/src/validating_query_strings.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import List import requests from pydantic import BaseModel, Field @@ -17,14 +17,14 @@ class Todo(BaseModel): userId: int - id_: Optional[int] = Field(alias="id", default=None) + id_: int | None = Field(alias="id", default=None) title: str completed: bool @app.get("/todos") @tracer.capture_method -def get_todos(completed: Annotated[Optional[str], Query(min_length=4)] = None) -> List[Todo]: # (3)! +def get_todos(completed: Annotated[str | None, Query(min_length=4)] = None) -> List[Todo]: # (3)! url = "https://jsonplaceholder.typicode.com/todos" if completed is not None: diff --git a/examples/idempotency/src/bring_your_own_persistent_store.py b/examples/idempotency/src/bring_your_own_persistent_store.py index 83ab27b8c4e..50e3595e94f 100644 --- a/examples/idempotency/src/bring_your_own_persistent_store.py +++ b/examples/idempotency/src/bring_your_own_persistent_store.py @@ -1,6 +1,6 @@ import datetime import logging -from typing import Any, Dict, Optional +from typing import Any, Dict import boto3 from botocore.config import Config @@ -24,8 +24,8 @@ def __init__( status_attr: str = "status", data_attr: str = "data", validation_key_attr: str = "validation", - boto_config: Optional[Config] = None, - boto3_session: Optional[boto3.session.Session] = None, + boto_config: Config | None = None, + boto3_session: boto3.session.Session | None = None, ): boto3_session = boto3_session or boto3.session.Session() self._ddb_resource = boto3_session.resource("dynamodb", config=boto_config) diff --git a/examples/logger/src/bring_your_own_formatter_from_scratch.py b/examples/logger/src/bring_your_own_formatter_from_scratch.py index 425f00b0d28..7bcffa1d0af 100644 --- a/examples/logger/src/bring_your_own_formatter_from_scratch.py +++ b/examples/logger/src/bring_your_own_formatter_from_scratch.py @@ -1,13 +1,13 @@ import json import logging -from typing import Any, Dict, Iterable, List, Optional +from typing import Any, Dict, Iterable, List from aws_lambda_powertools import Logger from aws_lambda_powertools.logging.formatter import BasePowertoolsFormatter class CustomFormatter(BasePowertoolsFormatter): - def __init__(self, log_record_order: Optional[List[str]] = None, *args, **kwargs): + def __init__(self, log_record_order: List[str] | None = None, *args, **kwargs): self.log_record_order = log_record_order or ["level", "location", "message", "timestamp"] self.log_format = dict.fromkeys(self.log_record_order) super().__init__(*args, **kwargs) diff --git a/examples/streaming/src/assert_transformation_module.py b/examples/streaming/src/assert_transformation_module.py index eac11abd4af..cc9b1dc4984 100644 --- a/examples/streaming/src/assert_transformation_module.py +++ b/examples/streaming/src/assert_transformation_module.py @@ -1,5 +1,5 @@ import io -from typing import IO, Optional +from typing import IO from aws_lambda_powertools.utilities.streaming.transformations import BaseTransform @@ -9,7 +9,7 @@ def __init__(self, input_stream: IO[bytes], encoding: str): self.encoding = encoding self.input_stream = io.TextIOWrapper(input_stream, encoding=encoding) - def read(self, size: int = -1) -> Optional[bytes]: + def read(self, size: int = -1) -> bytes | None: data = self.input_stream.read(size) return data.upper().encode(self.encoding) diff --git a/examples/streaming/src/s3_json_transform.py b/examples/streaming/src/s3_json_transform.py index 30c31b0f32c..8588498e38b 100644 --- a/examples/streaming/src/s3_json_transform.py +++ b/examples/streaming/src/s3_json_transform.py @@ -1,5 +1,5 @@ import io -from typing import IO, Optional +from typing import IO import ijson @@ -11,10 +11,10 @@ class JsonDeserializer(io.RawIOBase): def __init__(self, input_stream: IO[bytes]): self.input = ijson.items(input_stream, "", multiple_values=True) - def read(self, size: int = -1) -> Optional[bytes]: + def read(self, size: int = -1) -> bytes | None: raise NotImplementedError(f"{__name__} does not implement read") - def readline(self, size: Optional[int] = None) -> bytes: + def readline(self, size: int | None = None) -> bytes: raise NotImplementedError(f"{__name__} does not implement readline") def read_object(self) -> dict: diff --git a/package-lock.json b/package-lock.json index 3a9b1de6b24..cda2d626edd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,13 +8,13 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.1135.1" + "aws-cdk": "^2.1136.0" } }, "node_modules/aws-cdk": { - "version": "2.1135.1", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1135.1.tgz", - "integrity": "sha512-g1jcMfWlyYtGamFJ/kPBOCuchl3NfwTF2UwOLTIDN0nJbGm84EAO+c8DlYnaemM8UmKFkdoq4BGdmiNL5nHWwA==", + "version": "2.1136.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1136.0.tgz", + "integrity": "sha512-n6kCL9R9uuvb7WXEwiSs3rYGwnTy9AHHmxOT5Pj5/++E4PYz2bLDXIxzoiOMIj5maoyC52PTe/0GezFV+O0ILQ==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/package.json b/package.json index 47d70c3bbbc..d429b6b453c 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,6 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.1135.1" + "aws-cdk": "^2.1136.0" } } diff --git a/poetry.lock b/poetry.lock index 092b4c16046..6234daec8f2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -52,45 +52,69 @@ test = ["coverage", "mypy", "pexpect", "ruff", "wheel"] [[package]] name = "ast-serialize" -version = "0.5.0" +version = "0.8.0" description = "Python bindings for mypy AST serialization" optional = false python-versions = ">=3.7" groups = ["dev"] files = [ - {file = "ast_serialize-0.5.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-win32.whl", hash = "sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c"}, - {file = "ast_serialize-0.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb"}, - {file = "ast_serialize-0.5.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101"}, - {file = "ast_serialize-0.5.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a"}, - {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211"}, - {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf"}, - {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9"}, - {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee"}, - {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809"}, - {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43"}, - {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934"}, - {file = "ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759"}, - {file = "ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887"}, - {file = "ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27"}, - {file = "ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d"}, - {file = "ast_serialize-0.5.0-cp39-abi3-win32.whl", hash = "sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a"}, - {file = "ast_serialize-0.5.0-cp39-abi3-win_amd64.whl", hash = "sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590"}, - {file = "ast_serialize-0.5.0-cp39-abi3-win_arm64.whl", hash = "sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642"}, - {file = "ast_serialize-0.5.0.tar.gz", hash = "sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6"}, + {file = "ast_serialize-0.8.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:3d822605fa7bb326ef868d25fafced7fc660fa46d9b90c02ea86d5e2f5d325f7"}, + {file = "ast_serialize-0.8.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:2efa40b068197d5efb62655b43baadb842ed71c4958cccd3e8b86a35726f0119"}, + {file = "ast_serialize-0.8.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:db1b957291bca08c7e72f43a12357b2948e20775d970e3fc3dac0aa3160ab725"}, + {file = "ast_serialize-0.8.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdc0d5b18ff8fb364e87923e47c0a91d0d69dbcaeaa274591f7fd26892cc3a3a"}, + {file = "ast_serialize-0.8.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9da7330f3e235bf7da89b8d39205c6350fc0c08a85379743f2df9fff87d6d980"}, + {file = "ast_serialize-0.8.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3186969ee66a9863b00acc6523ace44c56974eecb348a7ea4b228d9f0b80e19"}, + {file = "ast_serialize-0.8.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40a57b73731be45da4fa41430c4d5dc94a24b3a4faba7b9e069978c0402064ea"}, + {file = "ast_serialize-0.8.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5075b9da3ef807eda752502446dfecea3b381c4900b7e27a5d5f4f899eb39951"}, + {file = "ast_serialize-0.8.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:293cc1c5bfa741f8e3fbe8175b9c07beee487c9a6fdbb25a5acad9f1df2d30a9"}, + {file = "ast_serialize-0.8.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e0910c3442a75216dde0f102d854ba2aaa71d2482e0ee213630b9bf29584fba3"}, + {file = "ast_serialize-0.8.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:43dd6d596879bb1cb8a12cc9dae7bb10090a39a35883026c24f82488a195619a"}, + {file = "ast_serialize-0.8.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:8c9d537f59e936392cfd3597789d1390304dd659efc3c486ce7f40fb6b8a9f53"}, + {file = "ast_serialize-0.8.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:f0190a33d7f97c65e9069f7a7f40499eea6b5cbe260c558378109caf20ce934b"}, + {file = "ast_serialize-0.8.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:77308ae6c5cf5264cc0f01a7c556ec77a9e68eb1f61b093534d698139fdc3b14"}, + {file = "ast_serialize-0.8.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:8d53a23f27e1ed3a36b2d26fd2a1a6228c8e85a1ed62ff7cdb44bd610769f20a"}, + {file = "ast_serialize-0.8.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ffa5e7cb08f96fed9121f77b224151e41caf88feab9d652bb46c78202b6fbeda"}, + {file = "ast_serialize-0.8.0-cp314-cp314t-win32.whl", hash = "sha256:fa70ed4dea0bb18b30a1789c77baa701d0ef30c474f2ccabdea61e25623a8827"}, + {file = "ast_serialize-0.8.0-cp314-cp314t-win_amd64.whl", hash = "sha256:d8b3c8eee4c1baef9d4e84d2a59a805501617127be42615cb48970b15b0892b6"}, + {file = "ast_serialize-0.8.0-cp314-cp314t-win_arm64.whl", hash = "sha256:ac4f0a83c55a9b782f79ad55a5247b7db123c1db405959791c2ef886e9710c9f"}, + {file = "ast_serialize-0.8.0-cp315-abi3.abi3t-macosx_10_12_x86_64.whl", hash = "sha256:86b8a1e6d90467345356098b040150e82fbc26d24a7a202224b13dc1f6264ca0"}, + {file = "ast_serialize-0.8.0-cp315-abi3.abi3t-macosx_11_0_arm64.whl", hash = "sha256:39e92ff8e8cb45947fe9007174b2950e1fb098e6abd00266a13cd3bcf6675068"}, + {file = "ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c85d8d18db5b2dfcb3b7e38a4d600ca35504c0ed8a6f75cd1c811e4ffe248a15"}, + {file = "ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9830ff7e764f74d9eefb01170c61a9f0fd2c027dac5fcb72e064decd57d56371"}, + {file = "ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6479d9722a4cd21b578f5478074c41e6169f04811996ec881655560f703a5bba"}, + {file = "ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a63bed264e818cd83eec11feed0f50aa162542b91132ef58afebc857182763a5"}, + {file = "ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d187197d234aa45d6cfa2b096be5f666e8cc2e7eb3722d0ab8926293cf5720c"}, + {file = "ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_31_riscv64.whl", hash = "sha256:2d39a56282cfcc0d8eeea37267c754be59c98d48505c23b1dae5c6011f3813dd"}, + {file = "ast_serialize-0.8.0-cp315-abi3.abi3t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f7cc5f10386994c0f4844f1e6d6a97127e9b478660eb6dec2b257644f0acab64"}, + {file = "ast_serialize-0.8.0-cp315-abi3.abi3t-musllinux_1_2_aarch64.whl", hash = "sha256:6102f2f985c2e542be85cd857678ec9356fefa792b93cadfadd31139f5696f27"}, + {file = "ast_serialize-0.8.0-cp315-abi3.abi3t-musllinux_1_2_armv7l.whl", hash = "sha256:3a8660fe66667b76a6e9dccd1d33e66b229fde3b308db991c041609226c005b6"}, + {file = "ast_serialize-0.8.0-cp315-abi3.abi3t-musllinux_1_2_i686.whl", hash = "sha256:e7266307e5fba39836edb79def8608887af48820508bff3c5f2941e1e04d1534"}, + {file = "ast_serialize-0.8.0-cp315-abi3.abi3t-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca7e6fd1ad845d1cc649dc2ecd499db2f8f46af5bf8da7b70dd858774cc038b"}, + {file = "ast_serialize-0.8.0-cp315-abi3.abi3t-musllinux_1_2_riscv64.whl", hash = "sha256:2880350b13d3eae69a0d70bc1fb6c9bfaca4dbd0e20ba8cd1aa483080b56ff06"}, + {file = "ast_serialize-0.8.0-cp315-abi3.abi3t-musllinux_1_2_x86_64.whl", hash = "sha256:ab0f9a59f7d63d0d441b56b9a818b273705264352d5115cfee12e940e816d958"}, + {file = "ast_serialize-0.8.0-cp315-abi3.abi3t-win32.whl", hash = "sha256:0485a25ef519c62e749ee3c1ad8070e591b380d67226349eb5a70b228dc1ac4a"}, + {file = "ast_serialize-0.8.0-cp315-abi3.abi3t-win_amd64.whl", hash = "sha256:bd84d60bca7079e741be4ac5dbe237751a59d7f6f9f0126b11880d63822cbe16"}, + {file = "ast_serialize-0.8.0-cp315-abi3.abi3t-win_arm64.whl", hash = "sha256:057769b5921336eb2d9124f2a731b42ed05ffdac559b840dbdf6f3937cf153dc"}, + {file = "ast_serialize-0.8.0-cp315-cp315-pyemscripten_2026_5_wasm32.whl", hash = "sha256:a02cbed7d8bfdcdee88edaac12bd50d53d9953aaa2e1852ef078625be5f1c0b5"}, + {file = "ast_serialize-0.8.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:e1bd223df0f6c96b396975fa604cb33bce53d9b4a0185490be4c4a289f7c9c87"}, + {file = "ast_serialize-0.8.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:ddd3b61f45c132da66c5476b281891e08c1fd87fbdabe8a6973e1622efc85f06"}, + {file = "ast_serialize-0.8.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f9caa63fad8241257ae401b5ff0a64026c6adb36b8e86cbe8782d9ea505daf6"}, + {file = "ast_serialize-0.8.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3926fa117b5e65019853a2969966d11c7175af377a3425991f3fe73784412405"}, + {file = "ast_serialize-0.8.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:485f1113af805e9e170b95ef993ca3fbd4f89c04bab25c58b4fc632d854801ab"}, + {file = "ast_serialize-0.8.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccebbed24f1281062d5852353c72c47502955926cfcb8345ffb3a44d87ff3d3"}, + {file = "ast_serialize-0.8.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:252f883290d1cdb728eb7fe1d9a7221b88af5a329aae0bc91ddee4dafb820331"}, + {file = "ast_serialize-0.8.0-cp39-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:96abc072ad29db8d02194afd47d68987322622787daceae82398d7b69f3ba2e6"}, + {file = "ast_serialize-0.8.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9118ad3e369727060b2696fc4078f250ecffca4248ba87f537f55cea9f9dce06"}, + {file = "ast_serialize-0.8.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:f359df4bd921918af8bebd142a376c77511d7151cc8ba852760b587b5a4a54f3"}, + {file = "ast_serialize-0.8.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:e94f9121d13fa36cbf21314783c77d05ae3a0868decd18cf5233fdcc6de49ac8"}, + {file = "ast_serialize-0.8.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:54f95b486018d262bcb387a9afd96f0da74508b442762b80c769454a6fbb3ee3"}, + {file = "ast_serialize-0.8.0-cp39-abi3-musllinux_1_2_ppc64le.whl", hash = "sha256:4c38b915511e32bc718c49dbce98ff9af36bac0ad6a604f58000cd5e3aecdba7"}, + {file = "ast_serialize-0.8.0-cp39-abi3-musllinux_1_2_riscv64.whl", hash = "sha256:9a2ef9cf12f2de4f1028c42c1dd7d775255e0fb3e5bb48896c97e35ef52366fe"}, + {file = "ast_serialize-0.8.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6f18048fe9f6dd266bd577cdec48bdcecb74faaa01fe941324435483b013ed2a"}, + {file = "ast_serialize-0.8.0-cp39-abi3-win32.whl", hash = "sha256:31883542dd6c94d178f5db3d32fbd69c5eb88b3a7c018e7ac8cc0c45195ddbed"}, + {file = "ast_serialize-0.8.0-cp39-abi3-win_amd64.whl", hash = "sha256:861794565b06337005c1447ef23103a3d5a627d08bdc827870d00d0b28ef5f51"}, + {file = "ast_serialize-0.8.0-cp39-abi3-win_arm64.whl", hash = "sha256:b2a5978662fd4db463dfb4b974d2b10ac6430b98f5333aabc7051909df3561d0"}, + {file = "ast_serialize-0.8.0.tar.gz", hash = "sha256:6c37c43e4004dfb42d321ddedc569dc17ff4259296f3af577c9ea46a809bc010"}, ] [[package]] @@ -138,20 +162,19 @@ zstandard = ["zstandard"] [[package]] name = "aws-cdk-asset-awscli-v1" -version = "2.2.282" +version = "2.2.292" description = "A library that contains the AWS CLI for use in Lambda Layers" optional = false -python-versions = "~=3.10" +python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "aws_cdk_asset_awscli_v1-2.2.282-py3-none-any.whl", hash = "sha256:24139da0eb1be59f8cfda22c6343d51e8d50bb89b5052b049cfab92683de7790"}, - {file = "aws_cdk_asset_awscli_v1-2.2.282.tar.gz", hash = "sha256:f86e61653927f77fb235b5ec148c955c610117430c869d182c8b20f7e07e2df2"}, + {file = "aws_cdk_asset_awscli_v1-2.2.292-py3-none-any.whl", hash = "sha256:01cfb33e2913df2d63448b0954ea4ed1bcb1d064514b4b7aa266eda915e8ebfc"}, + {file = "aws_cdk_asset_awscli_v1-2.2.292.tar.gz", hash = "sha256:06da203eeaecbbbf5f1ecd3b12140104e6a59b6a7f6182cfbda5c5deda4b6344"}, ] [package.dependencies] -jsii = ">=1.130.0,<2.0.0" +jsii = ">=1.139.0,<2.0.0" publication = ">=0.0.3" -typeguard = "2.13.3" [[package]] name = "aws-cdk-asset-node-proxy-agent-v6" @@ -250,60 +273,57 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-aws-lambda-python-alpha" -version = "2.259.0a0" +version = "2.266.0a0" description = "The CDK Construct Library for AWS Lambda in Python" optional = false python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "aws_cdk_aws_lambda_python_alpha-2.259.0a0-py3-none-any.whl", hash = "sha256:6ab839026a26fd9e9c7d0df04e08dbbfe32e9a22d89726175e165e2b5da268f2"}, - {file = "aws_cdk_aws_lambda_python_alpha-2.259.0a0.tar.gz", hash = "sha256:5d061cb7ba7a76e5699e7a0cc1aaa2ba329d5242ddf945a79eda717c287d2e09"}, + {file = "aws_cdk_aws_lambda_python_alpha-2.266.0a0-py3-none-any.whl", hash = "sha256:be7c34c7296d9e6c478df9065510b2013a52d27629be6d90b4c9221043e71077"}, + {file = "aws_cdk_aws_lambda_python_alpha-2.266.0a0.tar.gz", hash = "sha256:eb7bb2890c722dc7d49851c61f8df8f7dd339a9135216e8f007c5c5be1b05cdb"}, ] [package.dependencies] -aws-cdk-lib = ">=2.259.0,<3.0.0" +aws-cdk-lib = ">=2.266.0,<3.0.0" constructs = ">=10.5.0,<11.0.0" -jsii = ">=1.133.0,<2.0.0" +jsii = ">=1.139.0,<2.0.0" publication = ">=0.0.3" -typeguard = "2.13.3" [[package]] name = "aws-cdk-cloud-assembly-schema" -version = "54.2.0" +version = "54.21.0" description = "Schema for the protocol between CDK framework and CDK CLI" optional = false -python-versions = "~=3.10" +python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "aws_cdk_cloud_assembly_schema-54.2.0-py3-none-any.whl", hash = "sha256:a7038bffa1aaf3365b72147987396bcf0b9951c3b53b2eebfc181b7cb4227067"}, - {file = "aws_cdk_cloud_assembly_schema-54.2.0.tar.gz", hash = "sha256:2e3a05fca6a28f49811b7b011fce12b03dd0adb15c37a0ad2d1b16d8d66fe95a"}, + {file = "aws_cdk_cloud_assembly_schema-54.21.0-py3-none-any.whl", hash = "sha256:e5951260bb7ca20956240a96f90aa423c33467a5a37b40e338dd4e2c9c02fb0c"}, + {file = "aws_cdk_cloud_assembly_schema-54.21.0.tar.gz", hash = "sha256:bd66b07ab1a1570801219a3ad3e438a6853db284771cff7aa5e18935b2b3dd0c"}, ] [package.dependencies] -jsii = ">=1.132.0,<2.0.0" +jsii = ">=1.139.0,<2.0.0" publication = ">=0.0.3" -typeguard = "2.13.3" [[package]] name = "aws-cdk-lib" -version = "2.260.0" +version = "2.267.0" description = "Version 2 of the AWS Cloud Development Kit library" optional = false python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "aws_cdk_lib-2.260.0-py3-none-any.whl", hash = "sha256:41363a6fd72261ce64055b6c90538cf9b9ee2854faca7d2c56316656214f56ea"}, - {file = "aws_cdk_lib-2.260.0.tar.gz", hash = "sha256:94412d6539b543e898aa3a408a39c4d68be06c992938f8191d12f6ab44e546df"}, + {file = "aws_cdk_lib-2.267.0-py3-none-any.whl", hash = "sha256:83e269742e10069b5df80b2b99ec55ffb097f31cbf62317b6cf44eb63d4a9430"}, + {file = "aws_cdk_lib-2.267.0.tar.gz", hash = "sha256:2778f1befdda7401ad064d60f5442858c2dad2a1a87591264ca6f17da6ebd4a2"}, ] [package.dependencies] -"aws-cdk.asset-awscli-v1" = "2.2.282" +"aws-cdk.asset-awscli-v1" = "2.2.292" "aws-cdk.asset-node-proxy-agent-v6" = ">=2.1.2,<3.0.0" -"aws-cdk.cloud-assembly-schema" = ">=54.0.0,<55.0.0" +"aws-cdk.cloud-assembly-schema" = ">=54.11.0,<55.0.0" constructs = ">=10.5.0,<11.0.0" -jsii = ">=1.133.0,<2.0.0" +jsii = ">=1.139.0,<2.0.0" publication = ">=0.0.3" -typeguard = "2.13.3" [[package]] name = "aws-encryption-sdk" @@ -1402,103 +1422,133 @@ typeguard = "2.13.3" [[package]] name = "coverage" -version = "7.14.3" +version = "7.15.4" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "coverage-7.14.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:360bec1f58e7243e3405d3bdf7a1a8115aa9b448d54dc7cd6f7b7e0e9406b62e"}, - {file = "coverage-7.14.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed68faa5e85de2f3e400bc3f122e5c82735a58c8bb24b9f63a2215954ba17b2d"}, - {file = "coverage-7.14.3-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:830c1fca669c572dec37ce9c838224ee45aac5be0f6961edf871e82e49d6537c"}, - {file = "coverage-7.14.3-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:a64caee2193563601dbaaa55fe2dcf597debef04a2f8f1fa8a07aa4bb7ac7a1e"}, - {file = "coverage-7.14.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0096fd7559178f0cc9cf088f2dbd2a02ef85bacaa69732c633517286b4494610"}, - {file = "coverage-7.14.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6197e5a00183c11a8ce7c6abd18be1a9189fd8399084ffc95196f4f0db4f2137"}, - {file = "coverage-7.14.3-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7dfe427045520d6abca33687dfef767b4f635015893a1816c5decb12eb72ce18"}, - {file = "coverage-7.14.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:9a3f142070eb7b82fc4085a55d887396f9c4e21250bccebe2ba22502c45b9647"}, - {file = "coverage-7.14.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:64b2055bb6e0dc945af35cdeceb3633e6ed9273475ef3af85592410fd6803803"}, - {file = "coverage-7.14.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:1551b4caac3e3ec9f2bfcec6bf3776e01c0edbdd2e240431a50ca1a1aac72c27"}, - {file = "coverage-7.14.3-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:583d50d59142f8549470bd6390471d0fe8b8c8d69d6a0f28ac71e05380cef640"}, - {file = "coverage-7.14.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0bb8a6bc7015efdf8a928753b25da1b9ca2d6f24ef04d2ee0688e486f32aae7"}, - {file = "coverage-7.14.3-cp310-cp310-win32.whl", hash = "sha256:d48400185564042287dc487c1f016a3397f18ab4f4c5d5ec36edc218f7ffa35b"}, - {file = "coverage-7.14.3-cp310-cp310-win_amd64.whl", hash = "sha256:eadea7aba74e40adee867a8c0eec17b820b061d308a4b014f7a0e118c2b0aa61"}, - {file = "coverage-7.14.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e574801e1d643561594aa021206c46d80b257e9853087090ba97bed8b0a509d3"}, - {file = "coverage-7.14.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f82b6bb7d75a2613e85d07cefa3a8c973d0544a8993337f6e2728e4a1e94c305"}, - {file = "coverage-7.14.3-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a2335ea5fed26af2e831094964fa3f8fae60b45f7e37fcc2d3b615b2add3ad87"}, - {file = "coverage-7.14.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fbb8c3a98e779013786ae01d229662aeacbc77100efbd3f2f245219ace5af700"}, - {file = "coverage-7.14.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ac082660de8f429ba0ea363595abb838998570b9a7546777c60f413ab902bbde"}, - {file = "coverage-7.14.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:8ac012839ff7e396030f1e94e10553a431d14e4de2ab65cb3acb72bbd5628ca2"}, - {file = "coverage-7.14.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5952f8c1bda2a5347154450379316e6dfa4d934d62ca35f6784451e6f55074fb"}, - {file = "coverage-7.14.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8cf0f2509acb4619e2471a1951089054dd58ebea7a912066d2ea56dd4c24ca4a"}, - {file = "coverage-7.14.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2e41fd3aab806770008279a93879b0924b16247e09ab537c043d08bbca53b4ab"}, - {file = "coverage-7.14.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f0a47095963cfe054e0df178daca95aec21e680d6076da807c3add28dfe920f7"}, - {file = "coverage-7.14.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:a090cbf9521e78ffdb2fcf448b72902afe9f5923ff6a12d5c0d0120200348af9"}, - {file = "coverage-7.14.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4d310baf69a4fbe8a098ce727e4808a34866ac718a6f759ae659cbd3221358bc"}, - {file = "coverage-7.14.3-cp311-cp311-win32.whl", hash = "sha256:74fdd718d88fe144f4579b8747873a07ec3f04cb837d5faec5a25d9e22fa31a8"}, - {file = "coverage-7.14.3-cp311-cp311-win_amd64.whl", hash = "sha256:cc96aa922e21d4bc5d5ed3c915cef27dfcbc13686f47d5e378d647fbfba655a2"}, - {file = "coverage-7.14.3-cp311-cp311-win_arm64.whl", hash = "sha256:c66f9f9d4f1e9712eb9b1de5310f881d4e2188cfcba5065e1a8490f38687f2c4"}, - {file = "coverage-7.14.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3d74ff26299c4879ce3a4d826f9d3d4d556fd285fde7bbce3c0ef5a8ab1cec24"}, - {file = "coverage-7.14.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:96150a9cf3468ea20f0bc5d0e21b3df8972c31480ef90fa7614b773cc6429665"}, - {file = "coverage-7.14.3-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:27d07a46500ba23515b838dbcf52512026af04090755cf6cc64166d88c9b9a1a"}, - {file = "coverage-7.14.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:621e13c6108234d7960aaf5762ab5c3c00f33c30c15af06dcbff0c73bf112727"}, - {file = "coverage-7.14.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4b60ca6d8af70473491a15a343cbabab2e8f9ea66a4376e81c7aa24876a6f977"}, - {file = "coverage-7.14.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c90a7cdd5e380e1ce02f19792e2ac2fbfbf177e35a27e69fd3e873b30d895c0c"}, - {file = "coverage-7.14.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5d788e5fd55347eef06ca0732c77d04a264de67e8ff24631270cdff3767a60cf"}, - {file = "coverage-7.14.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:62c7f79db2851c95ef020e5d28b97afde3daf9f7febcd35b53e05638f729063f"}, - {file = "coverage-7.14.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:90f7608aeb5d9b60b523b9fb2a4ee1973867cc4865a3f26fe6c7577073b70205"}, - {file = "coverage-7.14.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1e3b91f9c4740aeb571ecf82e5e8d8e4ab62d34fcb5a5d4e5baa38c6f7d2857c"}, - {file = "coverage-7.14.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:c946099774a7699de03cbd0ff0a64e21aed4525eed9d959adde4afe6d15758ef"}, - {file = "coverage-7.14.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:16b206e521feb8b7133a45754643dead0538489cf8b783b90cf5f4e3299625fd"}, - {file = "coverage-7.14.3-cp312-cp312-win32.whl", hash = "sha256:ea3169c7116eb6cdf7608c6c7da9ecfcb3da40688e3a510fac2d1d2bafd6dc35"}, - {file = "coverage-7.14.3-cp312-cp312-win_amd64.whl", hash = "sha256:7ea52fc08f007bcc494d4bb3df3851e95843d881860ba38fe2c64dc100db5e7d"}, - {file = "coverage-7.14.3-cp312-cp312-win_arm64.whl", hash = "sha256:8cec0ad652ec57790970d817490105bd917d783c2f7b38d6b58a0ca312e1a336"}, - {file = "coverage-7.14.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:47968988b367990ae4ab17523790c38cd125e02c6bfd379b6022be2d40bdc38c"}, - {file = "coverage-7.14.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0ee68f5c34812780f3a7063382c0a9fcbb99985b7ddcdcaa626e4f3fb2e0783a"}, - {file = "coverage-7.14.3-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:fa9e5c6857a7e80fa22ace5cf3550ae392bbfc322f1d8dd2d2d5a8be38cec027"}, - {file = "coverage-7.14.3-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:98a0859b0e98e43e1178a9402e19c8127766b14f7109a374d976e5a62c0e5c73"}, - {file = "coverage-7.14.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69918344541ed9c8368566c2adc03c0e33d4550d7faa87d1b35e49b6a3286ea9"}, - {file = "coverage-7.14.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b7f300ac92cd4b570724c8ffbbd0c130fee298d2447f41d5a3abf58976fae1de"}, - {file = "coverage-7.14.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:11a7ec9f97ab950f4c5af62229befc7faf208fdbc0116d3902d7e306cf2c5abd"}, - {file = "coverage-7.14.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a571bd889cd36c5922ce8e42e059f9d37d02301531d11374afa4c87a578625d5"}, - {file = "coverage-7.14.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:de76caefc8deabb0dd1678b6a980be97d14c8d87e213ac194dbf8b09e96d63fb"}, - {file = "coverage-7.14.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:d20a15c622194234161535459affa8f7905830391c9ccfa060d495dbfe3a1c7f"}, - {file = "coverage-7.14.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:b488bd4b23397db62e7a9459129d01ff06a846582a732efd24834b24a6ada498"}, - {file = "coverage-7.14.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a3693b4153394d265f44fb855fdc80e72403024d4d6f91c4871b334d028e4e0"}, - {file = "coverage-7.14.3-cp313-cp313-win32.whl", hash = "sha256:338b19131ab1a6b767b462bfcbaa692e7ae22f24463e39d49b02a83410ff6b37"}, - {file = "coverage-7.14.3-cp313-cp313-win_amd64.whl", hash = "sha256:b3d77f7f196abdef7e01415de1bce09f216189e83e58159cfeef2b92d0464994"}, - {file = "coverage-7.14.3-cp313-cp313-win_arm64.whl", hash = "sha256:e6230e688c7c3e65cedd41a774eb4ec221adc6bfee13768231015b702d5e4150"}, - {file = "coverage-7.14.3-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:605ab2b566a22bd94834529d66d295c364aba84afd3e5498285c7a524017b1fc"}, - {file = "coverage-7.14.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a3c2134809e80fac091bfed18a6991b5a5eb5df5ae32b17ac4f4f99864b73dd7"}, - {file = "coverage-7.14.3-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c02efd507227bde9969cab0db8f48890eb3b5dcad6afac57a4792df4133543ce"}, - {file = "coverage-7.14.3-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1bb93c2aa61d2a5b38f1526546d95cf4132cb681e541a337bf8dfd092be816e5"}, - {file = "coverage-7.14.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f502e948e03e866538048bba081c075caaa62e5bda6ea5b7432e45f587eb462a"}, - {file = "coverage-7.14.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9973ef2463f8e6cfb61a6324126bb3e17d67a85f22f58d856e583ea2e3ca6501"}, - {file = "coverage-7.14.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9be4e7d4c5ca0427889f8f9d614bd630c2be741b1de7699bca3b2b6c0e41003e"}, - {file = "coverage-7.14.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a574912f3bde4b0619f6e97d01aa590b70998859244793769eb3a6df78ee56d3"}, - {file = "coverage-7.14.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:e343fb086c9cd780b38622fea7c369acd64c1a0724312149b5d769c387a2b1f5"}, - {file = "coverage-7.14.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:3c68df8e61f1e09633fefc7538297145623957a048534368c9d212782aa5e845"}, - {file = "coverage-7.14.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:3e5b550a128419373c2f6cec28a244207013ef15f5cbcff6a5ca09d1dfaaf027"}, - {file = "coverage-7.14.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2bfc4dd0a912329eccc7484a7d0b2a38032b38c40663b1e1ac595f10c457954b"}, - {file = "coverage-7.14.3-cp314-cp314-win32.whl", hash = "sha256:0423d64c013057a06e70f070f073cec4b0cbc7d2b27f3c7007292f2ff1d52965"}, - {file = "coverage-7.14.3-cp314-cp314-win_amd64.whl", hash = "sha256:92c22e19ce64ca3f2ad751f16f14df1468b4c231bd6af97185063a9c292a0cb3"}, - {file = "coverage-7.14.3-cp314-cp314-win_arm64.whl", hash = "sha256:41de778bd41780586e2b04912079c73089ab5d839624e28db3bdb26de638da92"}, - {file = "coverage-7.14.3-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:8427f370ca67db4c975d2a26acfc0e5783ca0b52444dbc50278ace0f35445949"}, - {file = "coverage-7.14.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:d8e88f335544a47e22ae2e45b344772925ec65166555c958720d5ed971880891"}, - {file = "coverage-7.14.3-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:beaab199b9e5ceaf5a225e16a9d4df136f2a1eae0a5c20de1e277c8a5225f388"}, - {file = "coverage-7.14.3-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b3ff255799f5a1676c71c1c32ec01fd043aa09d57b3d95764b24992757184784"}, - {file = "coverage-7.14.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:878832eaac515b62decfa76965aed558775f86bf1fc8cca76993c0c84ae31aed"}, - {file = "coverage-7.14.3-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:611e62cb9386096d81b63e0a05330750268617231e7bd598e1fe77482a2c58a5"}, - {file = "coverage-7.14.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:02c41de2a88011b893050fc9830267d927a50a215f7ad5ec17349db7090ccf26"}, - {file = "coverage-7.14.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:526ce9721116af23b1065089f0b75046fe521e7772ab94b641cd66b7a0421889"}, - {file = "coverage-7.14.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e4ed44705ca4bead6fc977a8b741f2145608289b33c8a9b42a95d0f15aedbf4d"}, - {file = "coverage-7.14.3-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:2415902f385a23dcc4ccd26e0ba803249a169af6a930c003a4c715eeb9a5444e"}, - {file = "coverage-7.14.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:b75ee850fc2d7c831e883220c445b035f2224de2ba6103f1e56dbd237ab913f7"}, - {file = "coverage-7.14.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:dc9b4e35e7c3920e925ba7f14886fd5fbe481232754624e832ddba66c7535635"}, - {file = "coverage-7.14.3-cp314-cp314t-win32.whl", hash = "sha256:7b27c822a8161afbe48e99f1adfb098d270ae7e0f7d7b0555ce110529bdb69cc"}, - {file = "coverage-7.14.3-cp314-cp314t-win_amd64.whl", hash = "sha256:39e1dbbb6ff2c338e0196a482558a792a1de3aa64261196f5cdb3da016ad9cda"}, - {file = "coverage-7.14.3-cp314-cp314t-win_arm64.whl", hash = "sha256:68520c90babfa2d560eca6d497921ed3a4f469623bd709733124491b2aa8ef3f"}, - {file = "coverage-7.14.3-py3-none-any.whl", hash = "sha256:fb7e18afb6e903c1a92401a2f0501ac277dca527bb9ca6fe1f691a8a0026a0e8"}, - {file = "coverage-7.14.3.tar.gz", hash = "sha256:1a7563a443f3d53fdeb040ec8c9f7466aed7ca3dc5891aa09d3ca3625fa4387f"}, + {file = "coverage-7.15.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d0be6daac4cce6b8c8dc65886bae1b082ddbca4da8e5cbb5e15166acf253e264"}, + {file = "coverage-7.15.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b24e078eabcd6a9caa8b0713f9bc1eeb310bcc960a29d45a3b4fcd4b16d5b11d"}, + {file = "coverage-7.15.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:cfe20cc8cf8821d4fe54f89106cbf06aa27f37b5bbe3535568065a81539b4150"}, + {file = "coverage-7.15.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:83cf06cdd687677742caff1a9134833b7a8b75f111519d2cb0e0ba1b9a851e15"}, + {file = "coverage-7.15.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8fa4de68e2a752468ff14b4e15db7def689a71be759e826a31ccecbef69c5fd0"}, + {file = "coverage-7.15.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4dff9daa47d83120c3ec38ce921214242944a832aa04e903e50b5b7ebac8972d"}, + {file = "coverage-7.15.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a093fd37229918976f602aa07aa59e0973cde82186f220c8e197f721f5be0ce4"}, + {file = "coverage-7.15.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:317db01a2cb02552fd67e2b1cca77a4b528a2a277176c5e0bf2cecbb639d3f54"}, + {file = "coverage-7.15.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8ee3838dcb656602c3b51e16aed9bfb0822f8d8d6d1c5966d32ec8c104be8e20"}, + {file = "coverage-7.15.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:425920379052ff1fe465268f3361d35804a241bbdd5a1b592c8cb60df4c52325"}, + {file = "coverage-7.15.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:69bb2400abef928e365ea7d4d9925169ada78ed2295546780002d4b65de3df88"}, + {file = "coverage-7.15.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:81661f82d302484e3119e7c80c519c02fa9bcc2a6b339baf67d67bc89c580f04"}, + {file = "coverage-7.15.4-cp310-cp310-win32.whl", hash = "sha256:cb476b2e828ecb71cb6b6a928d23fd20a7ddb501188022dae1c37499149cc338"}, + {file = "coverage-7.15.4-cp310-cp310-win_amd64.whl", hash = "sha256:3fc2130bf37df31852a8384f12601563a45a0024bccc6624f38355cba7a8d360"}, + {file = "coverage-7.15.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bbac5abad70df71019988f83f26ac7092ff2642975def4429e98dc7585ef3490"}, + {file = "coverage-7.15.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:357a173465c7ce028d07a95cc2b63b5bf59f50ecdd5ad75c5cbb78ada984048e"}, + {file = "coverage-7.15.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:21b803935e2efc3acebe9697197a294fccf5dc4e5382bd6369542ff7a7d2a1d7"}, + {file = "coverage-7.15.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7a2b580774a4786c1053157c0165e04476e03ff293993d7c148eee784a94bae6"}, + {file = "coverage-7.15.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a9464451c4efffe8d47ace5a540b10b0dc10e879066290f8600872b7f54a419d"}, + {file = "coverage-7.15.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:de602f34123c2f4af1c1869c6dbbbd60da6d5983bf01937367295d135cccbfce"}, + {file = "coverage-7.15.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6879ded16a27f3eeca19b900c147e81616e7054db451471a611b2755ee5249f7"}, + {file = "coverage-7.15.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:986be58c3ab54aae8d3496a6225eea74f760fdbe739b38bd442c7e8d133aa53b"}, + {file = "coverage-7.15.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c6103639613fe6c1e989082948419bc77a2d26b6c825c99d7fad25f7d3d87afc"}, + {file = "coverage-7.15.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d3af93dddb5659276c63bc16ac6466ac2033a70ca816097bbc06345b8ccdf571"}, + {file = "coverage-7.15.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:b10075e5421d04265766a6d1dac809bbeb8a946fbb23c8f82c227409b2190719"}, + {file = "coverage-7.15.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a67a9f78b2942d87ba8ce3059c642164d2aedd65337377fb52fe9803656bc5c7"}, + {file = "coverage-7.15.4-cp311-cp311-win32.whl", hash = "sha256:69484d1aca26e322e1c3ce03f09341e84524ababad2d7202161738d83cc9f82e"}, + {file = "coverage-7.15.4-cp311-cp311-win_amd64.whl", hash = "sha256:63fd6fcd1dd6e158f7eb78606e72933b3f6d01e7b747f99c6c12d764307a0fdc"}, + {file = "coverage-7.15.4-cp311-cp311-win_arm64.whl", hash = "sha256:ea82116c9893fa89e929b7f197ee5a1950a76e91cc5c85ba503fc02379d04890"}, + {file = "coverage-7.15.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d4fedd1f7f428f9fe83b1ead5e7cc87a43427be31aadafbac3ac0636dc7abb22"}, + {file = "coverage-7.15.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:37e2f0cdf58e2e1fed4e4d5a8f8786ae2f7eb80b478016876667dc4a01d60a97"}, + {file = "coverage-7.15.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:fb55d0e70bb15f2e81477613627286581414693d74ac7963c93a790dd453ca9d"}, + {file = "coverage-7.15.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:899b9da30f3c6c336566e3707495bb23e8302d39d862f01fa78c48b99b9437e2"}, + {file = "coverage-7.15.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d15715e8c46552827e5e4f30a35575a2dbcad14454cf3284c54483946bd16931"}, + {file = "coverage-7.15.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:002a438859f7b430bc99afeaf01a6d187dad1d0dc907b64cdeffc632a5db8fd8"}, + {file = "coverage-7.15.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e4193a04b518f7968f3099755f5509ee7cccc6dc2b92a6b14841934d22e222c9"}, + {file = "coverage-7.15.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e98dcc55d572b38e69d117da7e8e8efb8500f1f5eaf81ecd460a63220790b839"}, + {file = "coverage-7.15.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:af6c538498ce66c10d3fd541c2a8d5b03da5850355add34e6cba564210cb9e72"}, + {file = "coverage-7.15.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1d10025d96ea89fc2f73714dbc4cbd433fe012c1ac9e23f895d7728b238b6e52"}, + {file = "coverage-7.15.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:d802e1947603162ded419bff83ac7489820355d2b856dfb09206574e3a37ac0c"}, + {file = "coverage-7.15.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c2de40895718f91951b86712b4c5b694acaf9a0a49be13874896f599a1eed3f4"}, + {file = "coverage-7.15.4-cp312-cp312-win32.whl", hash = "sha256:5c3431b2161279b7db5c2a1aa58ae02e5cb8c3c42d93a5094be3f5537bd5b11b"}, + {file = "coverage-7.15.4-cp312-cp312-win_amd64.whl", hash = "sha256:6befeab5fb2b51c958ca4ac6c5d141a1e8240f4f76e46350f1911963deda49cd"}, + {file = "coverage-7.15.4-cp312-cp312-win_arm64.whl", hash = "sha256:67bc345491ab55b837277d76f5775d057e8c7f1ac44d890d8c2c82adde258c6f"}, + {file = "coverage-7.15.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c705b28feb2775dc82a25f1d473a370bc37ff93f5177f4e29ce2425f560f6921"}, + {file = "coverage-7.15.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3ff205ab5e3ecc670f6a4dd19d9cbf12ede53dd41cfc1e15716ec961ea6d314e"}, + {file = "coverage-7.15.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5172326e861a38b48b48befca15e0f477a26b283337a33a739c8fed229934e36"}, + {file = "coverage-7.15.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:12b59c90084e3234fb11184886bf4a40f4f16a8c8f867be2e087b81f8e8868d4"}, + {file = "coverage-7.15.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:349062d66f00b40fa2c1c222438bad25fabf755631b5d82937fe985c8008615c"}, + {file = "coverage-7.15.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4256ced708e598e05209bc1a8ab4074e04a51dba4c62fb45926a229af675ace7"}, + {file = "coverage-7.15.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d80f974b20782d9612c8b4c9beeca867074c7cf4079d1419843fa25a26428b25"}, + {file = "coverage-7.15.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2e179f19bfe1d31f8eeeaa12990194d761c4f62f0759661000bca6cd8729f40b"}, + {file = "coverage-7.15.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:8bc16bb47b7679670eceff71d78bfb7d6e5b143f6c2cd117487ec7c75e0d4b78"}, + {file = "coverage-7.15.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1cd685005cd2c4200adfc14cf39a603b9320efab3f18a8f7f156d20c9cc3345f"}, + {file = "coverage-7.15.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:337399ad2c93b3acd2a937627dae8b3e86b66707cd3d3e856347999aadf1ef8d"}, + {file = "coverage-7.15.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:96e257121228ec5cd2bb919276e94ac11074471bc37d68dbae0e8308cce15fff"}, + {file = "coverage-7.15.4-cp313-cp313-win32.whl", hash = "sha256:c65a9e0dfc6143491879da4e13b5e30f8be192055de508d737fb14601edbd22c"}, + {file = "coverage-7.15.4-cp313-cp313-win_amd64.whl", hash = "sha256:2ff8f5e9b8f7a94f0c11c45631eee103dbcb7d63274edd12c56efe1be690b3b4"}, + {file = "coverage-7.15.4-cp313-cp313-win_arm64.whl", hash = "sha256:6e0a8a5083b096487d6cfced94cdd514d8f5db6f113610fb36c0620edb1028cf"}, + {file = "coverage-7.15.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:770e9325ab5ea6d56f77e59b29ecfe0ac20b57a82a601876f90494a4dda0386f"}, + {file = "coverage-7.15.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d12b33a3a50a1676b7784dc8d00a0c6d66a9f2add4b85a041c19b6a7e53ef23c"}, + {file = "coverage-7.15.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5669c8378ebde86f5def7a25d29586631b58acc27ffde04399f678f3dfc6e082"}, + {file = "coverage-7.15.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ff97a14362eef486483ed44042ca2027ea257df6ff768e62358ee0c9776925ac"}, + {file = "coverage-7.15.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5a325e815318638aed1655d9c06e6d7c2d3d46c09231ce988070428a8762d734"}, + {file = "coverage-7.15.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:474223409d88eb20d2d6a0d37ea60e8647a65a90cc008dc1f0410af5f64f1e0d"}, + {file = "coverage-7.15.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7f2f62ae3cd189dd2e13aece758c57b3eecbd27be070dbd4cbd10936049e5dbf"}, + {file = "coverage-7.15.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:39ece820e29e0a2ba34b3ecb3be83c27e997eed8926f2ba6fe7ce7a0bda5843b"}, + {file = "coverage-7.15.4-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f21b56dcace11dfe013014201f577dcd592b2a9b72182d930361b47cf6f73f25"}, + {file = "coverage-7.15.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:93a3a0b662abcc10c73a47cbc72cd60f63618d6989fb2d1286e50eacd974f303"}, + {file = "coverage-7.15.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:141fae2cabf5569b782c10afc4c850ce10f618c13f8db54765cba99cc839da1f"}, + {file = "coverage-7.15.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:81294c7e6ab30c5f74c0353b11b2fd6320e72d9bee6ac73b357caa8b916323a5"}, + {file = "coverage-7.15.4-cp314-cp314-win32.whl", hash = "sha256:7bbd7d6418e0dab31a206af5203bd43ae36edb8e7fba1940b055d3e9249290d7"}, + {file = "coverage-7.15.4-cp314-cp314-win_amd64.whl", hash = "sha256:f0204ed122758782970526057093f448051a39db9d810d4e344bb87a3546f425"}, + {file = "coverage-7.15.4-cp314-cp314-win_arm64.whl", hash = "sha256:9e71e7bc71c686a123347ae47a0de33a175e797a85bb57b791492adf4eec8ed8"}, + {file = "coverage-7.15.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7c922735321eef3f87c280a3d39afff6b646723a2880b862cda4ac7a093b8aa8"}, + {file = "coverage-7.15.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f41c17c4668a655ce96d090d8d5ffdc24ef64b5a02f9753884d08483e8a4a41a"}, + {file = "coverage-7.15.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:46822e9b6ff1c6a72b518c162c44a8f45a61a1d609c51084bf5b16c023c5037b"}, + {file = "coverage-7.15.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3d6f4955b73b5445271379a59e3792b0d978f42d4a01e0cf7a67d9c33a3bb0a5"}, + {file = "coverage-7.15.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3fc9e047706fb4a9abb54f719d3aa643e80e5bb3818182c40aee01ac0f0247ba"}, + {file = "coverage-7.15.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:05e491d4f3165d62d4f5c8fd48dfeabf2ae8f42cbbd484319af33ea851b78982"}, + {file = "coverage-7.15.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:226c66e80ec0598d3b9b4874123df167ccca342aca8714f77cac6829688ee09c"}, + {file = "coverage-7.15.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:ac41cc14bebda0dbfb0628036b7f75706935c95bcc07fefe9a0f93614aa60a57"}, + {file = "coverage-7.15.4-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:8af623e5cd92080acddd02b38f2f406a2c3a0893c38950b211890361448fbf26"}, + {file = "coverage-7.15.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:07545711d4f0f32852a18f18ad11f76f0109909d09e78b9008b4cfc67e829429"}, + {file = "coverage-7.15.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:a0865421cfdc53654b342d515e5a233187590882d20b95752150e53f65460017"}, + {file = "coverage-7.15.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:460115e32ee40566476db5048f9bec1e842c127ad8e6f8be745aad3ac9cbc839"}, + {file = "coverage-7.15.4-cp314-cp314t-win32.whl", hash = "sha256:cbde877ef9dd7baf272b9bfef2b8a25edd45d9170fc326951dd20eb480335e85"}, + {file = "coverage-7.15.4-cp314-cp314t-win_amd64.whl", hash = "sha256:3da9e92d1c551fd7563833e9ade686efb0c4b7363ab7681a94283958c950bf5e"}, + {file = "coverage-7.15.4-cp314-cp314t-win_arm64.whl", hash = "sha256:3a54f5a0d85050c73a38f6793090ee83974531e67fe5e57a1da9bee11398aa5e"}, + {file = "coverage-7.15.4-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:2c9872e4d9dc5d3cf616bf4b382f5a00359305a5be666a3dd0b5cdb4e49597f9"}, + {file = "coverage-7.15.4-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:e101dbb4b9b72f0cddd8cdc8c9c5b47f456766f5e0ac82dbfb75e5c55409b78a"}, + {file = "coverage-7.15.4-cp315-cp315-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7d1abebdb047729e852b9c77a00497dfbeb11eb3a117e037d7dbc3ac8e5f5c54"}, + {file = "coverage-7.15.4-cp315-cp315-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d28a4a899354d0ea6214cc59b4fa19eefbce1b9ff1688ab579acf49e894bd3fb"}, + {file = "coverage-7.15.4-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ffb3c2aacea411cc7e1d27712490c11108e2de1d39019ae32915493a59a8b9ed"}, + {file = "coverage-7.15.4-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a9447978a92f405d301123cfd39ff49895490efb769a758fe2734c7f631bf8ce"}, + {file = "coverage-7.15.4-cp315-cp315-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:050467a7983b8e2fe7dd41a78bb30c3e7f8c0b8cafda14b1c46f8b5e3cf2dd3c"}, + {file = "coverage-7.15.4-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:d003b7a5708ddad5c206c79607a6b92abb6fc13c57d99d8a4468cc03a2941ced"}, + {file = "coverage-7.15.4-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:c38efe30fd74e5c19e9433f11fb1f5dc9c6522770971b7c6145bbaa413dc8800"}, + {file = "coverage-7.15.4-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:1f4f826d70f772ab8b0c052329580d7fe8b8abd191e4ce0c8f81aec6614665d3"}, + {file = "coverage-7.15.4-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:4a4bf917c9953f57c957be31c1cd504e3bd2f34d4a352b9d391a3025336f6768"}, + {file = "coverage-7.15.4-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:1c9bf40ebef178a45192c75c4964760bb261b0e6ad725da5fc4c93f674f19753"}, + {file = "coverage-7.15.4-cp315-cp315-win32.whl", hash = "sha256:43619d04c3671792d2c4706ae8bf45e265dc87bbd4078189ef8b847ea1e74be2"}, + {file = "coverage-7.15.4-cp315-cp315-win_amd64.whl", hash = "sha256:be619439dbcd31a2eab10b32de9fff62c26ed4bab69dc32b8363fdaaa0882809"}, + {file = "coverage-7.15.4-cp315-cp315-win_arm64.whl", hash = "sha256:def597967dafc2e8d97c9097ea453c464e0bb8ed38f193a43070f10dc623bb6d"}, + {file = "coverage-7.15.4-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:c7dbc748ac8a1e3e59a2b28bea47675e6e778081dbbf081bde0d75def2fcbe1d"}, + {file = "coverage-7.15.4-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:2413074a5ecbb61a01a7888fc72db0ca324d13588c5b38bc0dd8564cdcdfea26"}, + {file = "coverage-7.15.4-cp315-cp315t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:4e6f6f632b7b2f714bf7a1346e8f97b650ee71f3c298aaad42a2ab60f0f07645"}, + {file = "coverage-7.15.4-cp315-cp315t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8df457da2249d3c75ca2e5e835d59c725abfe92d27fdff6cd99eed85b51d5e9a"}, + {file = "coverage-7.15.4-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:050f66a08805acb5b8a23c6d4a517b1ecf82c08e81ed0e4bd727df065e5c6624"}, + {file = "coverage-7.15.4-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1587fb771d1ccceef708fdde1e5af8c7ed24b486b61d13a321acb7d8145390aa"}, + {file = "coverage-7.15.4-cp315-cp315t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8b4f1c3a69ca580f3fbd6b2046915f536d7f586874f25c1bb23add2a3c88d50f"}, + {file = "coverage-7.15.4-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:ffb58d7eff5b7f6ecc6fa21d6288ab7f968a212cb67d682c269c09b9eba3b66f"}, + {file = "coverage-7.15.4-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:d9df165544774574ee004b953023d1bebada1894a80b1052a43d798b0f676e67"}, + {file = "coverage-7.15.4-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:f9de0a24a4079b53e523b5c5e2c5945ec251ab486652659955187cf255a259bc"}, + {file = "coverage-7.15.4-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:150089274bdc9f940628552cb92844e0223c987f1902ab8efe9f45a2ec758d88"}, + {file = "coverage-7.15.4-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:a58a94fed5da6997d258e8f7668c1e195fbd04a691d781b7558f1e468f9e68bc"}, + {file = "coverage-7.15.4-cp315-cp315t-win32.whl", hash = "sha256:ebd5a6d8466ff30836572f3ba2cae8a5e8f85029b1c6d5e2ed338dc472a5166a"}, + {file = "coverage-7.15.4-cp315-cp315t-win_amd64.whl", hash = "sha256:288bde2a2d7ab6b6c2d7252fcde8b524387f2d970bdba9658fc6f8bbcaef0f9b"}, + {file = "coverage-7.15.4-cp315-cp315t-win_arm64.whl", hash = "sha256:68be5e1de60ff13c9095bbec0e5a7fa45b33b101752215b91345ea1f61c4a278"}, + {file = "coverage-7.15.4-py3-none-any.whl", hash = "sha256:964730a1e9de9c0cf11be6a1a3c79ce419c34882842abd256086ba4698705e84"}, + {file = "coverage-7.15.4.tar.gz", hash = "sha256:0548198fff07ccf4faf469520bce1c2eceb1ce3e62891921138dec10907f9d00"}, ] [package.dependencies] @@ -2250,14 +2300,14 @@ files = [ [[package]] name = "jsii" -version = "1.135.0" +version = "1.140.0" description = "Python client for jsii runtime" optional = false python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "jsii-1.135.0-py3-none-any.whl", hash = "sha256:bfab0cc3f99bfbc13683af2afb8d62522af867fb826fc825ab6b27fe636bb087"}, - {file = "jsii-1.135.0.tar.gz", hash = "sha256:3d860404e9e350beae0bdae48b473173653bd2be3a901c620feb656b690f9c2f"}, + {file = "jsii-1.140.0-py3-none-any.whl", hash = "sha256:aa24f27d15d8d7db1ff32a9c56074bc87e728b30330ead97fb149419a3721a50"}, + {file = "jsii-1.140.0.tar.gz", hash = "sha256:454c874d963a862f6b90bc013c45a720e51292659f57249d9cae7cb2a189ec0e"}, ] [package.dependencies] @@ -2347,103 +2397,150 @@ referencing = ">=0.31.0" [[package]] name = "librt" -version = "0.11.0" +version = "0.15.0" description = "Mypyc runtime library" optional = false python-versions = ">=3.9" groups = ["dev"] markers = "platform_python_implementation != \"PyPy\"" files = [ - {file = "librt-0.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6e94ebfcfa2d5e9926d6c3b9aa4617ffc42a845b4321fb84021b872358c82a0f"}, - {file = "librt-0.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ae627397a2f351560440d872d6f7c8dbb4072e57868e7b2fc5b8b430fe489d45"}, - {file = "librt-0.11.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc329359321b67d24efdf4bc69012b0597001649544db662c001db5a0184794c"}, - {file = "librt-0.11.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:7e82e642ab0f7608ce2fe53d76ca2280a9ee33a1b06556142c7c6fe80a86fc33"}, - {file = "librt-0.11.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:88145c15c67731d54283d135b03244028c750cc9edc334a96a4f5950ebdb2884"}, - {file = "librt-0.11.0-cp310-cp310-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9d36a51b3d93320b686588e27123f4995804dbf1bce81df78c02fc3c6eea9280"}, - {file = "librt-0.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d00f3ac06a2a8b246327f11e186a53a100a4d5c7ed52346367e5ec751d51586c"}, - {file = "librt-0.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:461bbceede621f1ffb8839755f8663e886087ee7af16294cab7fb4d782c62eeb"}, - {file = "librt-0.11.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:0cad8a4d6a8ff03c9b76f9414caccd78e7cfbc8a2e12fa334d8e1d9932753783"}, - {file = "librt-0.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f37aa505b3cf60701562eddb32df74b12a9e380c207fd8b06dd157a943ac7ea0"}, - {file = "librt-0.11.0-cp310-cp310-win32.whl", hash = "sha256:94663a21534637f0e787ec2a2a756022df6e5b7b2335a5cdd7d8e33d68a2af89"}, - {file = "librt-0.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:dec7db73758c2b54953fd8b7fe348c45188fe26b39ee18446196edd08453a5d4"}, - {file = "librt-0.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:93d95bd45b7d58343d8b90d904450a545144eec19a002511163426f8ab1fae29"}, - {file = "librt-0.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ee278c769a713638cdacd4c0436d72156e75df3ebc0166ab2b9dc43acc386c9"}, - {file = "librt-0.11.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f230cb1cbc9faaa616f9a678f530ebcf186e414b6bcbd88b960e4ba1b92428d5"}, - {file = "librt-0.11.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:5d63c855d86938d9de93e265c9bd8c705b51ec494de5738340ee93767a686e4b"}, - {file = "librt-0.11.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:993f028be9e96a08d31df3479ac80d99be374d17f3b78e4796b3fd3c913d4e89"}, - {file = "librt-0.11.0-cp311-cp311-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:258d73a0aa66a055e65b2e4d1b8cdb23b9d132c5bb915d9547d804fcaed116cc"}, - {file = "librt-0.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0827efe7854718f04aaddf6496e96960a956e676fe1d0f04eb41511fd8ad06d5"}, - {file = "librt-0.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7753e57d6e12d019c0d8786f1c09c709f4c3fcc57c3887b24e36e6c06ec938b7"}, - {file = "librt-0.11.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:11bd19822431cc21af9f27374e7ae2e58103c7d98bda823536a6c47f6bb2bb3d"}, - {file = "librt-0.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:22bdf239b219d3993761a148ffa134b19e52e9989c84f845d5d7b71d70a17412"}, - {file = "librt-0.11.0-cp311-cp311-win32.whl", hash = "sha256:46c60b61e308eb535fbd6fa622b1ee1bb2815691c1ad9c98bf7b84952ec3bc8d"}, - {file = "librt-0.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:902e546ff044f579ff1c953ff5fce97b636fe9e3943996b2177710c6ef076f73"}, - {file = "librt-0.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:65ac3bc20f78aa0ee5ae84baa68917f89fef4af63e941084dd019a0d0e749f0c"}, - {file = "librt-0.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46"}, - {file = "librt-0.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3"}, - {file = "librt-0.11.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67"}, - {file = "librt-0.11.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a"}, - {file = "librt-0.11.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a"}, - {file = "librt-0.11.0-cp312-cp312-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f"}, - {file = "librt-0.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b"}, - {file = "librt-0.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766"}, - {file = "librt-0.11.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d"}, - {file = "librt-0.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8"}, - {file = "librt-0.11.0-cp312-cp312-win32.whl", hash = "sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a"}, - {file = "librt-0.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9"}, - {file = "librt-0.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c"}, - {file = "librt-0.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894"}, - {file = "librt-0.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c"}, - {file = "librt-0.11.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea"}, - {file = "librt-0.11.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230"}, - {file = "librt-0.11.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2"}, - {file = "librt-0.11.0-cp313-cp313-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3"}, - {file = "librt-0.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21"}, - {file = "librt-0.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930"}, - {file = "librt-0.11.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be"}, - {file = "librt-0.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e"}, - {file = "librt-0.11.0-cp313-cp313-win32.whl", hash = "sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e"}, - {file = "librt-0.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47"}, - {file = "librt-0.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44"}, - {file = "librt-0.11.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd"}, - {file = "librt-0.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4"}, - {file = "librt-0.11.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8"}, - {file = "librt-0.11.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b"}, - {file = "librt-0.11.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175"}, - {file = "librt-0.11.0-cp314-cp314-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03"}, - {file = "librt-0.11.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c"}, - {file = "librt-0.11.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3"}, - {file = "librt-0.11.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96"}, - {file = "librt-0.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe"}, - {file = "librt-0.11.0-cp314-cp314-win32.whl", hash = "sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f"}, - {file = "librt-0.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7"}, - {file = "librt-0.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1"}, - {file = "librt-0.11.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72"}, - {file = "librt-0.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa"}, - {file = "librt-0.11.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548"}, - {file = "librt-0.11.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2"}, - {file = "librt-0.11.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f"}, - {file = "librt-0.11.0-cp314-cp314t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51"}, - {file = "librt-0.11.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2"}, - {file = "librt-0.11.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085"}, - {file = "librt-0.11.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3"}, - {file = "librt-0.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd"}, - {file = "librt-0.11.0-cp314-cp314t-win32.whl", hash = "sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8"}, - {file = "librt-0.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c"}, - {file = "librt-0.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253"}, - {file = "librt-0.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6bd72d903911d995ab666dbd1871f8b1e80925a699af8063fbf50053329fb05f"}, - {file = "librt-0.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ef69ac715f3cd8e5cd252cb2aebfa72c015492aacc339d5d7bf8fef3c62c677"}, - {file = "librt-0.11.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:624a40c4a4ad7773315c287276cd024509b2c66ff5904f504bfc08d2c70293ab"}, - {file = "librt-0.11.0-cp39-cp39-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:41dc19fe150b69716c8ece4f76773a9e8813fe3e35e032a58b4d46423fb8d7c0"}, - {file = "librt-0.11.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4e8bd98ea9c47ae90b319a087ab28dac493f1ffbc1ecd1f28fcdbf3b7e1108d1"}, - {file = "librt-0.11.0-cp39-cp39-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:84308fc49423ce6475d1c5d1985cd69a8ca9f0325fc7d5f81bb690a3f3625d4e"}, - {file = "librt-0.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ff0fbaf5f44a21beeb0110f2ab64f45135a9536a834b79c0d1ef018f2786bbfa"}, - {file = "librt-0.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:9c028a9442a18e266955d364ce42259136e79a7ba14d773e0d778d5f70cd56f1"}, - {file = "librt-0.11.0-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:9f1692105a02bcf853f355032a5fdc5494358ef83d8fd22d16de375c85cec3f5"}, - {file = "librt-0.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7a80a71e1fda83cc752a9141e87aae7fef279538597564d670e9ce513f286192"}, - {file = "librt-0.11.0-cp39-cp39-win32.whl", hash = "sha256:140695816ddf3c86eb972981a26f35efd871c44b0c3aed44c8cd01749386617f"}, - {file = "librt-0.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:92f7ff819c197fc30473190a12c2856f325ac90aabfccbeb2072d28cc2e234e3"}, - {file = "librt-0.11.0.tar.gz", hash = "sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1"}, + {file = "librt-0.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e1a49adf16a7c9d9646816c2946135527197b6fcf4347c7b8b761cf1bfbf4489"}, + {file = "librt-0.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:81a398f45b45a59200e13cd5ad1ae1d3f44334de98b148331afe2cdfee701c52"}, + {file = "librt-0.15.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4eafbaff06b9563f8b1c850621ce51605de05208e09d4d71ce490bc972b7b9e8"}, + {file = "librt-0.15.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:b0411b4066db926b80258c60dcb0e6db4c9cee312eab45b7e8866b17ddf9ada1"}, + {file = "librt-0.15.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:febb1ce6cac545a54e6b769982824e955a700fdd9fbf3a08a3d82c990968b57d"}, + {file = "librt-0.15.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b230acc1c3bfe2d6f2627ba2b95dc92e58aa494600e9722d0e6ccbc931e59702"}, + {file = "librt-0.15.0-cp310-cp310-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:6da110e5f314c19ab8478464d02ae18808ae73d522c15260fa4918acdcd64da9"}, + {file = "librt-0.15.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:eab9208b00ca55bf75983ec99f7bf13acc746a36102e98953addaad7f7ea1e1b"}, + {file = "librt-0.15.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:6c013cd3a1721e69e14380ada97eaa4b7b0cdf1c6b96fa765d4ea47c875088db"}, + {file = "librt-0.15.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:567b1c430f8bd560e689421468278ac5941bab4a05303b5d95b6ae10db03f451"}, + {file = "librt-0.15.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:29c4cab9df457b19672c39be7f384ebb2bc925c4e2684b8780c222b43eb36389"}, + {file = "librt-0.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:bccbd8e5b0bffb7106cf18eb1baa3d7194b1cebb3b4b1cdbd4bdb19382a6ee6c"}, + {file = "librt-0.15.0-cp310-cp310-win32.whl", hash = "sha256:8ae493ed5f659a7761c43d42f183db514536073ded9bcf671d2d1df47e29a07e"}, + {file = "librt-0.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:bc25fb356d0c7810bb49ff3df908ad1fda6995d660ab099ded69244ed7ab6053"}, + {file = "librt-0.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:823b92cf3c18ecd08afc70c42473888b41b6e8ef5046f3b82c05c154a2fa3d22"}, + {file = "librt-0.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c70bc1b602cf59917e8f0c7a2cbc8bcc6fbc14d5486136b00707a79619121d63"}, + {file = "librt-0.15.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:814ff83a25b5fce8b9c80c4dd803153fb5c5599fc74db9e022466938368957ef"}, + {file = "librt-0.15.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:57f5eeb6ad4c180de583b1038e61fe5fbd9796bb69a8a1c1a0c7ddbec4c8c60f"}, + {file = "librt-0.15.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:82909c8f7eb9952656b65d3147afde4cf8e6d5a991eebc86418b5e65843b0ab8"}, + {file = "librt-0.15.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f779070399f991400fc451719e0ea388eb7de313388bada2c127a35de05f798a"}, + {file = "librt-0.15.0-cp311-cp311-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bac89069bc496ebdf4f79ebb57bbd10d0b214c8454225deb672d91002bd17e18"}, + {file = "librt-0.15.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e0d00c708fb2f5822b152429b1ac80a58dbbbc3f6c232c4d13a3f7fcf2ea5b4c"}, + {file = "librt-0.15.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6c6624fe268625869485553dd7cc1daf30d22558215bb2a4ff16f67a9801a31a"}, + {file = "librt-0.15.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f56b397858a23dacf35ede366ed2212fdc03a6a57a1ad36468ad6e9dc5fac091"}, + {file = "librt-0.15.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:4388184646efe2054911c5b00a1077d6d1ee86a95b7e8ba96dc7850a809f3f40"}, + {file = "librt-0.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:97335f59082f9fe2ce6c2a9cc6433a0114bbb6cd4d5c09dd76c95c68b9f9a8b0"}, + {file = "librt-0.15.0-cp311-cp311-win32.whl", hash = "sha256:83380ffde38062a2e9bb55d83e74474f6614665528b98a6928720fc006dfffbb"}, + {file = "librt-0.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:f75720477ee05d509a310e856cacc8d909adc182f7b91193c207bcc26d7ee6db"}, + {file = "librt-0.15.0-cp311-cp311-win_arm64.whl", hash = "sha256:256237037a3ab001ae8d9803b2d43562a4c3aa38739843694349e4d5ebb0fd56"}, + {file = "librt-0.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e87bc679f86a99aa3b26e3c78eeb821a247c9a28eae48eaafcc32c3bf4c3bb9e"}, + {file = "librt-0.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:71599e011ac880e8e45d46047d714871894c7d4ab6f25626f8d4f89da21f368d"}, + {file = "librt-0.15.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c802434092b769b1d613ed2e13fac15fbfce1934a74bd10283b03c0fae231cd1"}, + {file = "librt-0.15.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:5500eeae393a184d14e1f35645962c27129d20c81afa4069e6ef826ebc2b3aaa"}, + {file = "librt-0.15.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6ecfc32dfb46fb7b565bcd6abf9412acf978775a998273d22888a6d7953730dd"}, + {file = "librt-0.15.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:89cc46cfd15022e35084355478c9ac809d90b1152222706ac9a7655ec21df6fa"}, + {file = "librt-0.15.0-cp312-cp312-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d5f51401d102c885b9ca509e62c79b1dbff286e1b9b047fde6f763780789356d"}, + {file = "librt-0.15.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:cc30523e3f1a23fb7511cc659834a0d01a1042bb9de359bc1c131cc4ec6c9656"}, + {file = "librt-0.15.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:59fe030d8ae4a57e3fb7756bf35a858de74e04066fc8555c53d0af979132af81"}, + {file = "librt-0.15.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5a6526a2a956bbb1e4ae3568c82e650fc99119c66bb011ea60715744955a2b4d"}, + {file = "librt-0.15.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:85ea21ec6730194d67156b0e0b5430ccb1d61f8b8b907e39b37f9812b74a13f0"}, + {file = "librt-0.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1e47b8ba865d7ede071a91a7163073bbaeb72541f1ef8a07d512c45c7b5007f2"}, + {file = "librt-0.15.0-cp312-cp312-win32.whl", hash = "sha256:a5207ec414d1c4a2a7231b2086970dc036f94293cdf338190984958a013a42f1"}, + {file = "librt-0.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:73b30cfa976659b3917c8f6153bdb0591c6a9ec6583599fd24a689b690622022"}, + {file = "librt-0.15.0-cp312-cp312-win_arm64.whl", hash = "sha256:a54cf9e0ef47b96af580849db5471142200568ce1e02cbf416addab551369570"}, + {file = "librt-0.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:db13ca398005abcbe538deda87b686d9bd08b7001cf40c4c06b444960ae10a26"}, + {file = "librt-0.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa1f1995789dca3698bc550aaceb09a51bd5df0a057ff84ff15296cd1975b801"}, + {file = "librt-0.15.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:55456ea87d8df21808446d03817be2f65e20391c1c615d9187440dff28cd08dc"}, + {file = "librt-0.15.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:5a86a5a08c2235316bdb359d5dbb6ce0abfca7fac06363103e2c5af571d92f95"}, + {file = "librt-0.15.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e56b6a368529bed262da40ce13f8fef590db0479819cca84f16a1f01ac356d0b"}, + {file = "librt-0.15.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:234d8d394721fa0d786af15ebf1f3fb7f3ed82fd1cd0cde45c2f247b5d4281d2"}, + {file = "librt-0.15.0-cp313-cp313-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d8363d7accb0286ac3a0e633f396e93800dafb8150494505daf9515bbda591f3"}, + {file = "librt-0.15.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0f0ee3644d951f31055ad07d77d92520e84505dd7a432cc4cd501dd70ee06785"}, + {file = "librt-0.15.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2cfd1a81a648806e6a7717be4cc4d1bb392fa229752bf8444ba365e381e984d6"}, + {file = "librt-0.15.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a6cd22c9da0d866558e46a041f1cc0c2bbb26b61b137b2347fa834c332e1d101"}, + {file = "librt-0.15.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:6d5225ef8801e4ea5e482fa9b5dfb891dd9ef6f6d870f1f25d449ca2c70ac218"}, + {file = "librt-0.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6d28a05796b99f749bf8794f17ba9ba1612d0076b802e9cfc62c554634e9ce3b"}, + {file = "librt-0.15.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:2067ff438048cead9d223ca5675bae2a25e520a7c3e6c1498bf9c6892d22caab"}, + {file = "librt-0.15.0-cp313-cp313-win32.whl", hash = "sha256:1cd3b721f24c206398b9e26da3c3a9c011e6e89d06f318ba8ebefc30f1003890"}, + {file = "librt-0.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:f395a4a9a03ac062dbe9a9f82e0c720502e590a38feee6a757bc82e9c63afbd8"}, + {file = "librt-0.15.0-cp313-cp313-win_arm64.whl", hash = "sha256:0a15cb554761247d84a3ec0cbdf4078d70725384f0e4662c0fa3b26266eb60ad"}, + {file = "librt-0.15.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:f5de7feedc56337a088eb15cd9fafa9938367362221d8cc62c642b7f94821993"}, + {file = "librt-0.15.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6c0eb900c0e91f4aebe680845242e614f1864edfd44106380d0752ac29522bf8"}, + {file = "librt-0.15.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e8c9a650a188e38bac005048cbe6342e81407782944d01934540ab75e417df21"}, + {file = "librt-0.15.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:92bfed8deec93df30286b9fe9e3b1dd17329cc076a192b4ee5ec223841d54953"}, + {file = "librt-0.15.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ec4b19788f835711a2072f9dbe6b03b3bf32ed1f0fb30cf399bdd59d9f0c33fa"}, + {file = "librt-0.15.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4c7bacb70930f3d0a56f4ecf1be474a1f0d941b01dd73b756f3c256d42cb879"}, + {file = "librt-0.15.0-cp314-cp314-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3e79f05e4a08b4d880342673312bbc895b56df7765605796f15902eb5367d3ae"}, + {file = "librt-0.15.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a417149c0cba4d50b61e992e5a15e69eaf96746609b461cc4ed168aeef6b79dd"}, + {file = "librt-0.15.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:da7a94d6a3411f579d72aa3e3bc5fbca7ed4549f3dbd7e5de3aa567333374285"}, + {file = "librt-0.15.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:856f743ae607f2c1380eccb566c0038a9fb3eabf0fc2be2704d76d9f73557239"}, + {file = "librt-0.15.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:779a6e7c894737e5983e7790a9c78c4000c30e23c9aada08081bdbea53b0fa60"}, + {file = "librt-0.15.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:96bb17dbe8bab3c0954fbebfc69ed395599de75b6bbc35e3270a878e15d4dd65"}, + {file = "librt-0.15.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:7220697efaa6e5348fc3d18ee7f8563d4bfecd9872b37ffb915bfc1d08840622"}, + {file = "librt-0.15.0-cp314-cp314-win32.whl", hash = "sha256:f54598964d357b1c5ab77cf5d92f21e598fe0e23cdbe9618480807f81b4eba15"}, + {file = "librt-0.15.0-cp314-cp314-win_amd64.whl", hash = "sha256:3ff5893a2c23d886aa9ce786de5ac6ddc74aeeaf90743682b74d920e117d2e28"}, + {file = "librt-0.15.0-cp314-cp314-win_arm64.whl", hash = "sha256:3722a099730704c9a3d70c879fc0f51daec25fe5f1555672d97bc595abeafb95"}, + {file = "librt-0.15.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:38c0c7d4b6fc06c3324b3f9162c8391bfc4fd9dde53afe1033ce7edb48d5a714"}, + {file = "librt-0.15.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8b2fdd7ead3c995c37940a790690660d0ca006c302db26cc51933f6766866fc3"}, + {file = "librt-0.15.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2fde98cf1fc4bac144ce23c2c4c017b924ba714509ea9334977b0b27050c837d"}, + {file = "librt-0.15.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:e3b461183c5fa7681b48560f91515f53a953122fb30c71e07abc67d7ddf58c38"}, + {file = "librt-0.15.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4bbcc257e3babea20a91715c361b24554ec4e8f51aa578568afc230799fe1a19"}, + {file = "librt-0.15.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b845b8d48088fad0cadc84be4b8fda63203be7e9237b71015b3925443c1f35ab"}, + {file = "librt-0.15.0-cp314-cp314t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b30e600e8f337b9bd7f39b86d9fdfedc73cc46e3d0f745931a23a234220bb7e2"}, + {file = "librt-0.15.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:64b0c8c35aa4c4ed79896359f3e0b285cbe4e610042106500da4811c322cc108"}, + {file = "librt-0.15.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:0da0d94cb802f32a0524653e7201f2cef72d5f700a5407678f5290483d4fcd08"}, + {file = "librt-0.15.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:4a6369168d371207339b1e50d4532b06a7121586141f82599505a3f315751d47"}, + {file = "librt-0.15.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:c434e072557ade9cbc642d052c89d031efe47d5c9614523619d0d74a02378e81"}, + {file = "librt-0.15.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c7eec6a42018bc1d45763b1c162d3d2bf7c3b9a1b0ed30d3e91dcba390efefcc"}, + {file = "librt-0.15.0-cp314-cp314t-win32.whl", hash = "sha256:6912fa5e635d74529ac7cdb1bdf6ca3af4453da8d1edbe0110ee1cb4ad407ebf"}, + {file = "librt-0.15.0-cp314-cp314t-win_amd64.whl", hash = "sha256:8e11699ed745931c395acd3621b07062e0f840efa6935aad87a64ed0995f0915"}, + {file = "librt-0.15.0-cp314-cp314t-win_arm64.whl", hash = "sha256:5d2a91724463bfed4f573cd7a9fdc856d2e230d0c0e5a61416a93481dccd8605"}, + {file = "librt-0.15.0-cp315-cp315-macosx_10_15_x86_64.whl", hash = "sha256:8443e38dcfcfdbcf5add5118c623efd788d65ac2e25756d6251a54a06a4d0aca"}, + {file = "librt-0.15.0-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:6d15a29033c57490cfe2069097c6fc4049e4e65ffbb749be7dc453b7c4c68965"}, + {file = "librt-0.15.0-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d2c05c729b589e734c09578bf5964be48a911765484840d017bbc84f49d4c4ad"}, + {file = "librt-0.15.0-cp315-cp315-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:fa60887537e1d0cd2d9982269d33a709bf54b195cd2b9364fc0a758022af5bd9"}, + {file = "librt-0.15.0-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d8bc24219b24c0af375718942ab75e3544b2763085f40f965be4326734ae8328"}, + {file = "librt-0.15.0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:86a21a7bd3fe3a419512ef424cc1c020f6771d0b29cfddff36d1635a855e63f0"}, + {file = "librt-0.15.0-cp315-cp315-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dbab647e88d90b3167b91efe7091e248653688ed4337e4f90907a722c7361bb9"}, + {file = "librt-0.15.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:d8edcf6f550e918dca779c069b9e156385c60b406f99fc7641f32c52f7193659"}, + {file = "librt-0.15.0-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:8b62076030baa2d8b1501a46bf0e19c27a489aa90671c55665bff7887f7660b0"}, + {file = "librt-0.15.0-cp315-cp315-musllinux_1_2_ppc64le.whl", hash = "sha256:d00d20d1818e82a07a0ee0aa89a98b17ed7916b92441090b683719cb20a59b6d"}, + {file = "librt-0.15.0-cp315-cp315-musllinux_1_2_riscv64.whl", hash = "sha256:4e6ee93fc3cf848dcbf0cce2eca73d8e7dcd0cc2b6df3a529d57750b30a4c55c"}, + {file = "librt-0.15.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:32896a0af72508ea979e0acb4e4c04cbeeae04938167950d535c83c45597167d"}, + {file = "librt-0.15.0-cp315-cp315-pyemscripten_2026_5_wasm32.whl", hash = "sha256:ec3ba415afaf951f6951b1dd16d3c8e4f540065fc382d7e70b823a79567ca374"}, + {file = "librt-0.15.0-cp315-cp315-win32.whl", hash = "sha256:d2813ba2503764f0450680c533d13df7cff9b49df1411062eded5f67db4195b9"}, + {file = "librt-0.15.0-cp315-cp315-win_amd64.whl", hash = "sha256:b87d67e33afaf265262f2a66db578284b88ee2e6fcd224579cb5c15518677ad8"}, + {file = "librt-0.15.0-cp315-cp315-win_arm64.whl", hash = "sha256:713bd7df21170b982e729e46870f31d6b437bd1a9b4648cffb529bd3c2ec5c4b"}, + {file = "librt-0.15.0-cp315-cp315t-macosx_10_15_x86_64.whl", hash = "sha256:3de789c82752730f94782a5ee518baf9c05edf85733aeaf73bb6e518755cdf54"}, + {file = "librt-0.15.0-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:e0b5deec9a8664eb722c797241970fd4aa1894d25fda36a1ddac0f7407606bd6"}, + {file = "librt-0.15.0-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5563302a8359bc2295bb7084d1a8ed1519df96afb30eb2aa4e0bff7b54228988"}, + {file = "librt-0.15.0-cp315-cp315t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:22d6263b9d39d7bbb286fa791945646e3218f1be2d693e36fb630f1d0e59cd13"}, + {file = "librt-0.15.0-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:39ffd14646190c454f0d86e0d256b33f00a87a26ab410e619773b841d0e41416"}, + {file = "librt-0.15.0-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c47318cd3a61401452de11282242937e3e057c4fd3dbaf601e269d0928a06c0a"}, + {file = "librt-0.15.0-cp315-cp315t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a56a1d4f859a82ca5b99fc4b82c9b027b15e3c455c5cd99e7d0719f27bb20b6c"}, + {file = "librt-0.15.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:077471b3182db4e17c36ae91555f36a4d2c00080b267f749bcad34a478a9a302"}, + {file = "librt-0.15.0-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:411ca4d1b905b860ceba7570dd6717a71dedaddcc4b0f77ece710aa41ee11f8d"}, + {file = "librt-0.15.0-cp315-cp315t-musllinux_1_2_ppc64le.whl", hash = "sha256:1256589e0b0adb31751d685a68bce29d73407ddf4ef05d4188f49d5dcf9566d9"}, + {file = "librt-0.15.0-cp315-cp315t-musllinux_1_2_riscv64.whl", hash = "sha256:f42b74a53e5f26a0ba0007411a7455b66c67ce4022a39cc1f56fc4efd65bcbab"}, + {file = "librt-0.15.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:291bf73caf78b9e88d6fae9bfd693207ff7d832e2fdbe2cf8e746bc13f5f892b"}, + {file = "librt-0.15.0-cp315-cp315t-win32.whl", hash = "sha256:c16d15ee371643ab48dc8248a3e680ebbeca573a13af2c3dd0c985b142d77162"}, + {file = "librt-0.15.0-cp315-cp315t-win_amd64.whl", hash = "sha256:dbd605739f228912dc49027cb764456b9757750bdc2b6b7773164db7096c6fd1"}, + {file = "librt-0.15.0-cp315-cp315t-win_arm64.whl", hash = "sha256:84d244b00604d17df3fc7736c327892d6bba66181254aa4087be807b6c342bdc"}, + {file = "librt-0.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0e2d0c0acf5b0ada7d045912b7cf787c21315c95b38b1fa939ef72d45d366b3d"}, + {file = "librt-0.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f9ca190fe9edc0eb08eec558a509a16d28d91c35667b8f043cba40ed5e77a959"}, + {file = "librt-0.15.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:80811e1c42386ea95c6fb30571d3250ad43d7863f883f787f70517f441150e59"}, + {file = "librt-0.15.0-cp39-cp39-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:88c2a17815c266e6d8180204ff62cb739ab869ada4a746d4c505331526ac58f1"}, + {file = "librt-0.15.0-cp39-cp39-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a5fa8f1f916988d0bf1afea005bda37f56ac41a18016e813ccf0097a8d460ca4"}, + {file = "librt-0.15.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:355e3a4c725225a14262004fc1872a552b9d3634b4f791a0dfc80804aafbfd55"}, + {file = "librt-0.15.0-cp39-cp39-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:fc1ed11c4ad0b91af24def2050f2840ea4567828e3dd058fbe608d982f6e5465"}, + {file = "librt-0.15.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1f4ef2e71db33df4309167ed7f1520c4fae5e611226e159fa9cf33f93e6ddb3d"}, + {file = "librt-0.15.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1a1a8cd430c7dd0c083f455cb1b328d7fc682b05c31b940906f7845bdff80881"}, + {file = "librt-0.15.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:04d5387b908676c0b8d5d2f5fb58373b4ea382d81f7a6f0fab8ea2a462bb4738"}, + {file = "librt-0.15.0-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:1172c6ad2a88b646e7fe3b480e3fac4ab4418b3443fd8a4061fdd531e0622fc7"}, + {file = "librt-0.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:52e8db01f603f5da0ca30987479acff98769382efc8e142fa3962395dcf3ffdb"}, + {file = "librt-0.15.0-cp39-cp39-win32.whl", hash = "sha256:e4c911f15a1652ca94ae9f1abd92e74cbb1b3597d2d92fdd556202f94e8cd455"}, + {file = "librt-0.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:68242379c9b65a582b6e97318a1e9fbd6d445e58954f2d437991c4804ab11578"}, + {file = "librt-0.15.0.tar.gz", hash = "sha256:4e66cbe84437497d951b799d3e1551291b6fb3d643820a7014b3655d57a59162"}, ] [[package]] @@ -2891,61 +2988,69 @@ dill = ">=0.4.1" [[package]] name = "mypy" -version = "2.1.0" +version = "2.3.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "mypy-2.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:11a6beb180257a805961aea9ec591bbd0bd17f1e18d35b8456d57aee5bedfedc"}, - {file = "mypy-2.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ef78c1d306bbf9a8a12f526c44902c9c28dffd6c52c52bf6a72641ce18d3849"}, - {file = "mypy-2.1.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c209a90853081ff01d01ee895cafe10f7db1474e0d95beaeef0f6c1db9119bbd"}, - {file = "mypy-2.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:47cebf61abde7c088a4e27718a8b13a81655686b2e9c251f5c0915a802248166"}, - {file = "mypy-2.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d57a90ae5e872138a425ec328edbc9b235d1934c4377881a33ec05b341acc9a8"}, - {file = "mypy-2.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:aea7f7a8a55b459c34275fc468ada6ca7c173a5e43a68f5dbe588a563d8a06b8"}, - {file = "mypy-2.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:c989640253f0d76843e9c6c1bbf4bd48c5e85ada61bde4beb37cb3eca035685e"}, - {file = "mypy-2.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a683016b16fe2f572dc04c72be7ee0504ac1605a265d0200f5cea695fb788f41"}, - {file = "mypy-2.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1a293c534adb55271fef24a26da04b855540a8c13cc07bc5917b9fd2c394f2ca"}, - {file = "mypy-2.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7406f4d048e71e576f5356d317e5b0a9e666dfd966bd99f9d14ca06e1a341538"}, - {file = "mypy-2.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e0210d626fc8b31ccc90233754c7bc90e1f43205e85d96387f7db1285b55c398"}, - {file = "mypy-2.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3712c20deed54e814eaaa825603bada8ea1c390670a397c95b98405347acc563"}, - {file = "mypy-2.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fcaa0e479066e31f7cceb6a3bea39cb22b2ff51a6b2f24f193d19179ba17c389"}, - {file = "mypy-2.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:0b1a5260c95aa443083f9ed3592662941951bca3d4ca224a5dc517c38b7cf666"}, - {file = "mypy-2.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:244358bf1c0da7722230bce60683d52e8e9fd030554926f15b747a84efb5b3af"}, - {file = "mypy-2.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4ec7c57657493c7a75534df2751c8ae2cda383c16ecc55d2106c54476b1b16f6"}, - {file = "mypy-2.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8161b6ff4392410023224f0969d17db93e1e154bc3e4ba62598e720723ae211"}, - {file = "mypy-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf03e12003084a67395184d3eb8cbd6a489dc3655b5664b28c210a9e2403ab0b"}, - {file = "mypy-2.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:20509760fd791c51579d573153407d226385ec1f8bcce55d730b354f3336bc22"}, - {file = "mypy-2.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:6753d0c1fdd6b1a23b9e4f283ce80b2153b724adcb2653b20b85a8a28ac6436b"}, - {file = "mypy-2.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:98ebb6589bb3b6d0c6f0c459d53ca55b8091fbc13d277c4041c885392e8195e8"}, - {file = "mypy-2.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:35aac3bb114e03888f535d5eb51b8bafbb3266586b599da1940f9b1be3ec5bd5"}, - {file = "mypy-2.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8de55a8c861f2a49331f807be98d90caeceeef520bde13d43a160207f8af613e"}, - {file = "mypy-2.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5fdf2941a07434af755837d9880f7d7d25f1dacb1af9dcd4b9b66f2220a3024e"}, - {file = "mypy-2.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e195b817c13f02352a9c124301f9f30f078405444679b6753c1b96b6eed37285"}, - {file = "mypy-2.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5431d42af987ebd92ba2f71d45c85ed41d8e6ca9f5fd209a69f68f707d2469e5"}, - {file = "mypy-2.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:767fe8c66dc3e01e19e1737d4c38ebefead16125e1b8e58ad421903b376f5c65"}, - {file = "mypy-2.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:ecfe70d43775ab99562ab128ce49854a362044c9f894961f68f898c23cb7429d"}, - {file = "mypy-2.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:7354c5a7f69d9345c3d6e69921d57088eea3ddeeb6b20d34c1b3855b02c36ec2"}, - {file = "mypy-2.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:49890d4f76ac9e06ec117f9e09f3174da70a620a0c300953d8595c926e80947f"}, - {file = "mypy-2.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:761be68e023ef5d94678772396a8af1220030f80837a3afd8d0aef3b419666f4"}, - {file = "mypy-2.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c90345fc182dc363b891350457ec69c35140858538f38b4540845afcc32b1aef"}, - {file = "mypy-2.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b84802e7b5a6daf1f5e15bc9fcd7ddae77be13981ffab037f1c67bb84d67d135"}, - {file = "mypy-2.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:022c771234936ceac541ebaf836fe9e2abeb3f5e09aff21588fe543ff006fe21"}, - {file = "mypy-2.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:498207db725cec88829a6a5c2fc771205fd043719ef98bc49aba8fb9fc4e6d57"}, - {file = "mypy-2.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7d5e5cad0efeba72b93cd17490cc0d69c5ac9ca132994fe3fb0314808aeeb83e"}, - {file = "mypy-2.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ff715050c127d724fd260a2e666e7747fdd83511c0c47d449d98238970aef780"}, - {file = "mypy-2.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:82208da9e09414d520e912d3e462d454854bed0810b71540bb016dcbca7308fd"}, - {file = "mypy-2.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e79ebc1b904b84f0310dff7469655a9c36c7a68bddb37bdd42b67a332df61d08"}, - {file = "mypy-2.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e583edc957cfb0deb142079162ae826f58449b116c1d442f2d91c69d9fced081"}, - {file = "mypy-2.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b33b6cd332695bba180d55e717a79d3038e479a2c49cc5eb3d53603409b9a5d7"}, - {file = "mypy-2.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:4f910fe825376a7b66ef7ca8c98e5a149e8cd64c19ae71d84047a74ee060d4e6"}, - {file = "mypy-2.1.0-py3-none-any.whl", hash = "sha256:a663814603a5c563fb87a4f96fb473eeb30d1f5a4885afcf44f9db000a366289"}, - {file = "mypy-2.1.0.tar.gz", hash = "sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633"}, + {file = "mypy-2.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:57a936373fc690c43a8cd7e7e12a35148e4ec5aa7698ad7fc0a9f918bdc5be41"}, + {file = "mypy-2.3.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d00d769056bde2f4e69c175071eba45cfb44fa1ed92bdfbfe64a93e0543b0cf0"}, + {file = "mypy-2.3.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2166b29228835e1f88ff411e96639e6ca3c7fdde84b62ec211f70f86b4051167"}, + {file = "mypy-2.3.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:83d36c2924df7426333abe7faf4724a7e1aab0d9fd41625e81b4683034b80c13"}, + {file = "mypy-2.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:f12fdb70459d0060dea40b29e52163a961b156106d68d57882a6a9f648983a53"}, + {file = "mypy-2.3.1-cp310-cp310-win_arm64.whl", hash = "sha256:e099200a1b1b1223a4951f0a90cbff1b8c91b250ba599dab1f7217a628144d90"}, + {file = "mypy-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94f04929f1c44c35fb0061e912087edaf504acede963a4a7d00680bd089d8531"}, + {file = "mypy-2.3.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f5d716048611e85ca9eefb2e1baa5d73ede389b5820ded260ea27c757d667af8"}, + {file = "mypy-2.3.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b091a455111214cb5c9d54a57b9618e9a49f9fe2a42e4e1ac86e9d104ed96ce8"}, + {file = "mypy-2.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:df12e20c9efd614738c71b390007ecd0181125afc4ccafca04d78a1d2eed2c01"}, + {file = "mypy-2.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:52eaf3a155f35cf80b40220288c861eb45f14a2340c1f6cbfbdb0feff32879d1"}, + {file = "mypy-2.3.1-cp311-cp311-win_arm64.whl", hash = "sha256:9b4eacbee8a69836c06eff6d0dd4e134a07c2b047755b30c08625fe214f322c6"}, + {file = "mypy-2.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a32bbbb940af990d3be0b8af321c7b6815bb1b3b48142fe7459b9cc5f58959ff"}, + {file = "mypy-2.3.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff715e45b2231a8e85de1d163d1b42791e4d7aab8f5145f85fee1b710b735aff"}, + {file = "mypy-2.3.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:858fc57d3d91fa728e33e7ad71def60fc6272694607b306cd3292db53ae39080"}, + {file = "mypy-2.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:851833db876e7b650f93719c74b7879a08e338979c96054fdfc3bfd90a486355"}, + {file = "mypy-2.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:4c5095a327483591c94e0c8d3ef9e50d4ab1369b541eae007c1f23bc2a41f6bb"}, + {file = "mypy-2.3.1-cp312-cp312-win_arm64.whl", hash = "sha256:bbfe022634a2a195406bd469e888d2eaf193b02ba7e607391cd7640374aaae3b"}, + {file = "mypy-2.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:114dff494000f18bd10d5d95d84b8567b26da60279ecbe838131841df20e635d"}, + {file = "mypy-2.3.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c8637731bb5eee3671eb2c3200827aa3564ed8a9309ecee4d1afe77e6d031bdb"}, + {file = "mypy-2.3.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1c80fbc405ed8020f5ff3802dc18cf060197bcdd3fbdd6a26ef2fd34dfdd5226"}, + {file = "mypy-2.3.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:84081f538ce27375045c02e3d7f81bd11d853400621ae245d87ce7b6c420ec74"}, + {file = "mypy-2.3.1-cp313-cp313-win_amd64.whl", hash = "sha256:e9144ac16fde007096f9563eb2041b4433c2d705c4218edeb79e7e9d01035ee6"}, + {file = "mypy-2.3.1-cp313-cp313-win_arm64.whl", hash = "sha256:77ad9529e67dca28e511f5cd5671436584ce91f6d3bac159a353158187b986ac"}, + {file = "mypy-2.3.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:192abaedf75da1bc0b1cef104927e70ec49c1ef0031cc4825c7ee10a438ed24d"}, + {file = "mypy-2.3.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf678dffd16efcda2c15cbd30e9ecc0081388e29ea23687a88e686ed92638dc3"}, + {file = "mypy-2.3.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8e036f06b41630f4c8a1d48f9ac6aa26acc65f8be089973f5519da643318f03f"}, + {file = "mypy-2.3.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:71af9c8a894e862b58e92abb08e53b05a384a1e5e5d6dc7cda59126211a53d82"}, + {file = "mypy-2.3.1-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:3c80cd23d85368bdd9f37d5231dfd97d35bcbf5bf41af96ef3a9b078ad1957f9"}, + {file = "mypy-2.3.1-cp314-cp314-win_amd64.whl", hash = "sha256:4956f34d145e145562a0a0bf367f642bbc85c04ec2baf47ae015947c3169a85d"}, + {file = "mypy-2.3.1-cp314-cp314-win_arm64.whl", hash = "sha256:cfb12e360242d23d91f5e978d94f58ea66acf5804c4fb6f2f794a20d4cb1b595"}, + {file = "mypy-2.3.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e5f1c50bb05b64e2026b52867e8d21106f01313c744a2c4ecc34c90d12e8d6e2"}, + {file = "mypy-2.3.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:667196b352f4cf304ded4c10f90cfc179263a1acfb3cdcfa984bdfd340d498bc"}, + {file = "mypy-2.3.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b9c53e395c12cad2c6d4b67d5da7c6057638a132d85c08b73646b18f802a0045"}, + {file = "mypy-2.3.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:18162b128c3f9c703cd35f5537446900b0d21a2549aa7a95d21380d2ef643fb0"}, + {file = "mypy-2.3.1-cp314-cp314t-win_amd64.whl", hash = "sha256:30c0477d4aab7b7f39c8397dc877f2c96b9fe5588ec379f372c56eb63d599f63"}, + {file = "mypy-2.3.1-cp314-cp314t-win_arm64.whl", hash = "sha256:6941ab3619377bc3f32ca02876b07d27f216f5201604b664d3937ea0fdd23bb4"}, + {file = "mypy-2.3.1-cp315-cp315-macosx_11_0_arm64.whl", hash = "sha256:6f041a6de52c9217ca125e78ba0a335cb7fd98a1c0580978e49ab2b126f70b57"}, + {file = "mypy-2.3.1-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5159ae60f5dbc3a498af5ba8365505808ac8031bc63f9e00304ad545d40bdd9b"}, + {file = "mypy-2.3.1-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:47a8a7a0a7f6f6e63995c0ac36fa0c07b127413fdc81f0439b7f3dccafd33561"}, + {file = "mypy-2.3.1-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:2329c0501293d4e1f33bc15d04d6304d65a1cdda967ee93a05c1e681a3923133"}, + {file = "mypy-2.3.1-cp315-cp315-pyemscripten_2026_5_wasm32.whl", hash = "sha256:bb26deed807bdb0457cf3e3f1cd7c4a1cf9d66864eaf1b4a61e06805d4c6b1f9"}, + {file = "mypy-2.3.1-cp315-cp315-win_amd64.whl", hash = "sha256:375d7013876a8233b2d05be185bfa09f689696cd999ce8b1cfe6acac5c80e8a3"}, + {file = "mypy-2.3.1-cp315-cp315-win_arm64.whl", hash = "sha256:586b3612214cceabb3c0f588c97e7d1e535393f06a60e912e994f6b3ace97523"}, + {file = "mypy-2.3.1-cp315-cp315t-macosx_11_0_arm64.whl", hash = "sha256:ef0c6335cda9d807f8193d8ff6204a72bc909fa9882aacbca14f43cdb7188306"}, + {file = "mypy-2.3.1-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e598c8c66401d26b150872154a286e6d484cf2789c3bb28a7556806298423021"}, + {file = "mypy-2.3.1-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eda22fd4efa9dcd39331d1dede9b5b8b8a7fd69af07592e778433da98610d29e"}, + {file = "mypy-2.3.1-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:2a0ba2e57847849fb0d1fcdabb32786d223095ed8bc121dfe322bcdb3d9c46bc"}, + {file = "mypy-2.3.1-cp315-cp315t-win_amd64.whl", hash = "sha256:3f7e865dd51f235f60a2dbcd8728a1c095f5ca28f095d48a725b84cd935735c4"}, + {file = "mypy-2.3.1-cp315-cp315t-win_arm64.whl", hash = "sha256:8ad80807dc3ab8ea978b1b2b6e4a657194ace1d4ef03e0e731aff1abd517da29"}, + {file = "mypy-2.3.1-py3-none-any.whl", hash = "sha256:6ed5c7e3419083268e5c9258bd1c1ef91af44a9e89374dbcaf37b775716e72eb"}, + {file = "mypy-2.3.1.tar.gz", hash = "sha256:47c1b1207258513a9d93495f69c8be9de73916186f0e52703e8c461b7a623419"}, ] [package.dependencies] -ast-serialize = ">=0.3.0,<1.0.0" -librt = {version = ">=0.11.0", markers = "platform_python_implementation != \"PyPy\""} +ast-serialize = ">=0.6.0,<1.0.0" +librt = {version = ">=0.13.0", markers = "platform_python_implementation != \"PyPy\""} mypy_extensions = ">=1.0.0" pathspec = ">=1.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} @@ -3373,15 +3478,15 @@ files = [ ] [[package]] -name = "py-cpuinfo" -version = "9.0.0" +name = "py-cpuinfo2" +version = "10.1.1" description = "Get CPU info with pure Python" optional = false -python-versions = "*" +python-versions = ">=3.9" groups = ["dev"] files = [ - {file = "py-cpuinfo-9.0.0.tar.gz", hash = "sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690"}, - {file = "py_cpuinfo-9.0.0-py3-none-any.whl", hash = "sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5"}, + {file = "py_cpuinfo2-10.1.1-py3-none-any.whl", hash = "sha256:adc53396bfb206e6498d078ec2ab407f85799ecd819584ac36a8f80a2d4d762d"}, + {file = "py_cpuinfo2-10.1.1.tar.gz", hash = "sha256:7861133863663f16e06eca63b12904ef100b5760415e92372dac0162799a4771"}, ] [[package]] @@ -3660,18 +3765,18 @@ testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] [[package]] name = "pytest-benchmark" -version = "5.2.3" +version = "5.3.0" description = "A ``pytest`` fixture for benchmarking code. It will group the tests into rounds that are calibrated to the chosen timer." optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "pytest_benchmark-5.2.3-py3-none-any.whl", hash = "sha256:bc839726ad20e99aaa0d11a127445457b4219bdb9e80a1afc4b51da7f96b0803"}, - {file = "pytest_benchmark-5.2.3.tar.gz", hash = "sha256:deb7317998a23c650fd4ff76e1230066a76cb45dcece0aca5607143c619e7779"}, + {file = "pytest_benchmark-5.3.0-py3-none-any.whl", hash = "sha256:920ab1dfcffa718d49aa15ba144c7e357bda59216a0dc308016cc1c7236f719d"}, + {file = "pytest_benchmark-5.3.0.tar.gz", hash = "sha256:358444d4e89be901ee2b6404fb043ac3d7684002ad7f3563cc153fca6339c965"}, ] [package.dependencies] -py-cpuinfo = "*" +py-cpuinfo2 = ">=10.1" pytest = ">=8.1" [package.extras] @@ -3719,14 +3824,14 @@ dev = ["pre-commit", "pytest-asyncio", "tox"] [[package]] name = "pytest-socket" -version = "0.8.0" +version = "0.8.1" description = "Pytest Plugin to disable socket calls during tests" optional = false python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "pytest_socket-0.8.0-py3-none-any.whl", hash = "sha256:81821ba59f07d7600fe2b551d8714f40b068bd46e8b6704c48664e9d60cdacb8"}, - {file = "pytest_socket-0.8.0.tar.gz", hash = "sha256:af9bb5f487da72be63573a6194cfac033b6c7a1c1561e150521105970f9e99f2"}, + {file = "pytest_socket-0.8.1-py3-none-any.whl", hash = "sha256:f9846bed1dcd96eed459e5e14795bbaf96715cf4e827891fe70773817ecb8ed4"}, + {file = "pytest_socket-0.8.1.tar.gz", hash = "sha256:2f57787914ad2e1308d09ce141b95c3e55741fbb4fb7b7556593a6b063e0c9c7"}, ] [package.dependencies] @@ -4301,30 +4406,30 @@ files = [ [[package]] name = "ruff" -version = "0.15.19" +version = "0.16.4" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" groups = ["dev"] files = [ - {file = "ruff-0.15.19-py3-none-linux_armv6l.whl", hash = "sha256:922d1eb283161564759bd49f507e91dc6112c15da8bd5b84ed714e086243cf86"}, - {file = "ruff-0.15.19-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:4d190d8f62a0b94aba8f721116538a9ee29b1e74d26650846ba9b99f0ae21c40"}, - {file = "ruff-0.15.19-py3-none-macosx_11_0_arm64.whl", hash = "sha256:5a2c86ba6870dd415a9d9eb8be94d7924ebec6a26ffc7958ec7ca29d4bff967d"}, - {file = "ruff-0.15.19-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82b432bc087264aea70fd25ac198918b70bd9e2aa0db4297b0bb91bbfbbc63ce"}, - {file = "ruff-0.15.19-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8530a09d03b3a8c994f8b559a7dcdabc690bcd3f78ef276c38c83166798ebf56"}, - {file = "ruff-0.15.19-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87bf21fb3875fe69f0eacc825411657e2e85589cce633c35c0adf1113649c62b"}, - {file = "ruff-0.15.19-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f9b229cb3ef56ecc2c1c8ebeca64b7a7740ccaef40a9eb097e78dde5a8560b83"}, - {file = "ruff-0.15.19-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6c754515be7b76afe6e7e62df7776709571bcfc1631183828afcf3bafa869e3"}, - {file = "ruff-0.15.19-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a498f82e0f4d8904c4e0aea5139cdfac1f39d19a3c51d491292f63a36e83b2e"}, - {file = "ruff-0.15.19-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:d48caa34488fb521fd0ef4aea2b0e8fe758298df044138f0d67b687a6a0d07ed"}, - {file = "ruff-0.15.19-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4171b6613effa9363cd46dd4f75bd1827b6d1b946b5e278ed0c600d305379445"}, - {file = "ruff-0.15.19-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:27c15b2a241dd4d995557949a094fe78b8ad99122a38ccae1595849bcc947b3f"}, - {file = "ruff-0.15.19-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ed03b7862d68f0a8771d50ee129980cbf1b113f96e250b73954bc292f689e0bb"}, - {file = "ruff-0.15.19-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:08143f0685ae278b30727ea72e90c61e5bd9c31b91aac4f5bb989538f73d24b8"}, - {file = "ruff-0.15.19-py3-none-win32.whl", hash = "sha256:8f47f0f92952af2557212bb10cf3e695cd4cf28b2c6e42cdb18ec6c9ebfa19da"}, - {file = "ruff-0.15.19-py3-none-win_amd64.whl", hash = "sha256:efeca47ee3f9d4a7162655a3b8e6ee4a878646044233978d4d2c1ff8cdd914f0"}, - {file = "ruff-0.15.19-py3-none-win_arm64.whl", hash = "sha256:6c6b607466e47349332eb1d9be52fb1467423fc07c217341af41cd0f3f0573be"}, - {file = "ruff-0.15.19.tar.gz", hash = "sha256:edc27f7172a93b32b102687009d6a588508815072141543ae603a8b9b0823063"}, + {file = "ruff-0.16.4-py3-none-linux_armv6l.whl", hash = "sha256:df4075f71ddac40b9934af60c3ec8a53047dd5a5fdc43224e6e4e8e9a27cb6f7"}, + {file = "ruff-0.16.4-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:0c95538517af68004306b0fb3214ff2f2af67a65092aee77cd9eb86db6656604"}, + {file = "ruff-0.16.4-py3-none-macosx_11_0_arm64.whl", hash = "sha256:963f83df8e69e575b64d67dd447ebbc917db41a14bf38d4593a4183e7aaa8255"}, + {file = "ruff-0.16.4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32a5057c7ff3f6e6480a48fccfb3a412a690f48a3d03ac5cf08177d6c2da3ade"}, + {file = "ruff-0.16.4-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b3dce8d9b0c57c265b91885a66a567d8ea1372e8eb4e250fa8e5e3f579e99cff"}, + {file = "ruff-0.16.4-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7dc651db49283c69f8e72c834eec4fe5573e4c646856aebece0ce385dceb2a80"}, + {file = "ruff-0.16.4-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3817b87dbcabc92f13b05019257c5b89b5b4d51b5fb20f56fb5235ceb723cd07"}, + {file = "ruff-0.16.4-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9fce1499134b2c8c68e5166f95705a5812062bb93aacc5f9873bb1a27084bc7"}, + {file = "ruff-0.16.4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2d812e482f5a7e02eee26cd73d2a37ebbdf47d795ea63ba1b89110ae93e9fb3"}, + {file = "ruff-0.16.4-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:6baaf984aa7976edf93d3b627fe2d1d22ee94bbca05fa6f90fc76d73924e3454"}, + {file = "ruff-0.16.4-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:bdfcf0b28662eb890372d50f92c283bb94e67e7635ed93c7fd533970acff7b2b"}, + {file = "ruff-0.16.4-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:b66b02cb9b04f537643cadf5768e5f98dc461890d530cb67113d71c8c76e605d"}, + {file = "ruff-0.16.4-py3-none-musllinux_1_2_i686.whl", hash = "sha256:8528bf9a4b291a60bf02ea453511e8ce6215bd2b982ee80405b66b008b6c30a0"}, + {file = "ruff-0.16.4-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:fbd85d2875fdd67e833213a651f613bbf25303abf6aa822a5121f4531195678d"}, + {file = "ruff-0.16.4-py3-none-win32.whl", hash = "sha256:312769988007aaeb8e189b443ccdd03c0e6374489e053467be6d96518ebff76e"}, + {file = "ruff-0.16.4-py3-none-win_amd64.whl", hash = "sha256:05d9d27a18c4bcbefada602480ec9e01e0bc949d432e0ced5df77edac195919c"}, + {file = "ruff-0.16.4-py3-none-win_arm64.whl", hash = "sha256:a3a61621c9b6f6a89573e938a080e648f1695baa3f58570a3a707bc51ff65a21"}, + {file = "ruff-0.16.4.tar.gz", hash = "sha256:13171aa9d9af2240ee3504e639de73122c67e74036de5ba2e1d01422cd17e3dc"}, ] [[package]] @@ -4975,42 +5080,42 @@ zstd = ["backports-zstd (>=1.0.0) ; python_version < \"3.14\""] [[package]] name = "valkey-glide" -version = "2.5.0" +version = "2.5.1" description = "Valkey GLIDE Async client. Supports Valkey and Redis OSS." optional = true python-versions = ">=3.9" groups = ["main"] markers = "extra == \"valkey\"" files = [ - {file = "valkey_glide-2.5.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:10bd8e942f7bd462cca4e8578f67c4e32d246cf42a736da89c5b6e55c1198e27"}, - {file = "valkey_glide-2.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d207e8d3ebaa7f434a73b4f29b46296c44d4277c93c6e0ce2db0c0a4037f4715"}, - {file = "valkey_glide-2.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8a04a8f00ccbaea1d43c933dacfaefc0779608e0f306053b7bc2c9a6ec71a22"}, - {file = "valkey_glide-2.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ee93ffd52845e5620774a65f43d751c9076505c9e29ea51263fcbc512893af1"}, - {file = "valkey_glide-2.5.0-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:df59c58ac08d66c4e730e7bab9f7e37c9cf30ca0e5b3ffa80f7e68abb0bfcc7b"}, - {file = "valkey_glide-2.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:40d67ea9bef44065809432e2a34193ada5a2a64b959f1f7b7572c5a055bdcb2d"}, - {file = "valkey_glide-2.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c4231e4290e06405729fd2b0c94febd6db861fe1a88e205627353d70e799473"}, - {file = "valkey_glide-2.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:284439b63dae97bc5dfa5266e39e9ba0868db9235932778599daa90b56fba2b2"}, - {file = "valkey_glide-2.5.0-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:95bc800473d5795e3db5eb9f64892cc0c4b79a4580320d51c90799f05ca815b9"}, - {file = "valkey_glide-2.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ea98b2b44bbfdfdc4fa6149b16136f67c59dd46e51f4e45c29136307c3177a3a"}, - {file = "valkey_glide-2.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9db2235a3190ec0b5bf3997c518a6c642f5e44c3a3c1ed70817ce5fc48815e6"}, - {file = "valkey_glide-2.5.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7893d63a3424ea43f9e2ab7ce2e31d628dea765f0ada09ab1b50b426f55d3863"}, - {file = "valkey_glide-2.5.0-cp313-cp313-macosx_10_7_x86_64.whl", hash = "sha256:cc6146d78545a85da2757ba0ac9d636b90fabdb45cc1a864f1c808381de942c5"}, - {file = "valkey_glide-2.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d8feb2a5ace38d1d88ba5c650b10273c5d862a55b0b5006d227aadd91e7c31e7"}, - {file = "valkey_glide-2.5.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bc80db5b2c191550ed716d28018520c7decc7853a2c2104c2d3654da3cd920e"}, - {file = "valkey_glide-2.5.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afecb53f774e7e376a757cda124bc08734b072cfdfcf703111b26afab5c24d2d"}, - {file = "valkey_glide-2.5.0-cp314-cp314-macosx_10_7_x86_64.whl", hash = "sha256:4a86f8451c5f8aa69f822782ba0ab64c77d8f6267844e2479b3267853dd076a5"}, - {file = "valkey_glide-2.5.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:97b1d1bde85abf9783952e65b134368d0a575b5978b73c60fdde1d69d6bc6a69"}, - {file = "valkey_glide-2.5.0-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2d442a9aa0a2685023850950d76acaa689df1581f3028468c965e71b9009a83"}, - {file = "valkey_glide-2.5.0-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c90d9bb9c49059f0ddd8b50b1e84e924c7a8bd261be82376ab09cefbbf2b233"}, - {file = "valkey_glide-2.5.0-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:eca2618c59301ffd093108714ef09e69d67b4f8745ad65b7fd5514d378d3b6be"}, - {file = "valkey_glide-2.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:19ccc9654f3e2da628fc7c6c15377a8f54046c73ab064530823649108a72fdef"}, - {file = "valkey_glide-2.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dc0a0fe39b1cadf81b15b91051f6101913bdb4b78d986d20a4dace152921f3c"}, - {file = "valkey_glide-2.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60315782ada98d4d49ae842535d5045b6e2d40366c05be3d49c9c4563f9012cf"}, - {file = "valkey_glide-2.5.0-pp311-pypy311_pp73-macosx_10_7_x86_64.whl", hash = "sha256:1bc0913efd997ed94136aac04d89fa73bb40525292a0182493c8c47bf24839b9"}, - {file = "valkey_glide-2.5.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:7d6c8127a6661d866c7fabb1830e6d8943536921e9f80033c6f095fdcec0ba28"}, - {file = "valkey_glide-2.5.0-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19a54a25fefa9e5839d0237625bf23e5f84df6a50eadac06181a9a99fb02e6c2"}, - {file = "valkey_glide-2.5.0-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47663a0432097746c3fc13f2e890280c003bfff7924f48f4f65c416750f4f368"}, - {file = "valkey_glide-2.5.0.tar.gz", hash = "sha256:21a9c037107af5ba3cdb27ed126abc02c75f9690dd6e82272f2a91042f4b8a2e"}, + {file = "valkey_glide-2.5.1-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:d66f47bbc5cea7155b0b3ca002043bfd950c09a9ac08e10923a6bcb0a3aa0a1c"}, + {file = "valkey_glide-2.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:47a666862faa47766d4c4814203c3b9f9a8cb466200fd5f71e330eef6ed0d8f1"}, + {file = "valkey_glide-2.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cecd82dab35f30d96785b1405ebe3a6931dd858c8f26a0b7a12b46609e75212"}, + {file = "valkey_glide-2.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44435ed9fdb6322a4b167c9f56fdc0145a1fab4736dd2659165bbb5358d3a68f"}, + {file = "valkey_glide-2.5.1-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:d9bbf26f9ea2b72ef0b8541dfefa479a82a69bdec77fce917192a262893edfda"}, + {file = "valkey_glide-2.5.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:94256d3335f4c31f19ad1ff02447d9eecd94b8c9e8d51c7b77811277c957e807"}, + {file = "valkey_glide-2.5.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d46a9903acb1204deefad88162ac77404f052c7d51ab9d5851d2335ed2fda1e8"}, + {file = "valkey_glide-2.5.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e5c17169d07564f0cc23b78c4904c8e03063c8750d8ccf413d229ce9a3092d5"}, + {file = "valkey_glide-2.5.1-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:75da4cb54fe6a0e03a78681237545aa0638dd5a6dd0ff51af6ff4cacf9f99443"}, + {file = "valkey_glide-2.5.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:787010bbce1b8f270ae5d74ca8af15bca3bbc625e1a5467fb01025864bc4e792"}, + {file = "valkey_glide-2.5.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de2e202a8376c6b67735bd589ce0e46683f8a782fcb1745b0b44cce768e13856"}, + {file = "valkey_glide-2.5.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ab1c7ce52b098fcb0ee6223136a024fc90a8ae1c600db298c30c044d1b47ee2"}, + {file = "valkey_glide-2.5.1-cp313-cp313-macosx_10_7_x86_64.whl", hash = "sha256:55c87ecc3146480adaddf42d659b688089ca417596208ca9df5c2249c8f9e6fe"}, + {file = "valkey_glide-2.5.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ae6b0cedd3d2aafdc53c460bdfe4d0319d10301fd2128a56d41486e49de88dfe"}, + {file = "valkey_glide-2.5.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8a3c5298899ea18fc7e40438643e2f8ee15955fe9bba66ce5daf3dfd29462f2"}, + {file = "valkey_glide-2.5.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb5e0094d576ce99a2453c9fdd923f70732db6f4b59a722c27c420343d96b75d"}, + {file = "valkey_glide-2.5.1-cp314-cp314-macosx_10_7_x86_64.whl", hash = "sha256:1bc5d0e0241aa5b78c398b981fe19801e36c09572c1dac69286a9a3c817e0b35"}, + {file = "valkey_glide-2.5.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ec658ed7770c05f3ea431ca1301e47d0a24cf27c4c23ca30eb030f7e0ac7488d"}, + {file = "valkey_glide-2.5.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2cdb26952b650e25af4a14360f65364b8015e49e2967779ba850c9e62c1f237"}, + {file = "valkey_glide-2.5.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:696635581f0692f640b94021b4cfbc2ec01108f6ae02f25dfea3cfdaa98331de"}, + {file = "valkey_glide-2.5.1-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:f5e733adc4718b93c5b228de7e543a6641e231d5839202ce7b22487e079059e7"}, + {file = "valkey_glide-2.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3ffd8f0fdb6ef982161a2350ad1562e5e345bea263b81304c7282f3385deac20"}, + {file = "valkey_glide-2.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6b81727c4d7a3b49f10172787296c87d6ef8d729fb958de358b278d5a6c563f"}, + {file = "valkey_glide-2.5.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12fff287f02caa9302d7c64d0520c3cee86e0f952ec55a537a4f9378889265d7"}, + {file = "valkey_glide-2.5.1-pp311-pypy311_pp73-macosx_10_7_x86_64.whl", hash = "sha256:f656ef6e722d6ab4a28bc66e36ef616dff28622bc712c41f4172ac1e7c4826d8"}, + {file = "valkey_glide-2.5.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:65b2add9f19a2e48080130ee968af45dc14e8457b5db20262703a4604afc478b"}, + {file = "valkey_glide-2.5.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c9b725afe94f0515e296003942d6c96c5090a956f2217f6305dc87fa14dfa51"}, + {file = "valkey_glide-2.5.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a131c08951b865f753f1bd42f7db19c6a96e7c4faf9dc78718f8909fc95eb8b4"}, + {file = "valkey_glide-2.5.1.tar.gz", hash = "sha256:b2efb23c987a995ad6ce2a72616996638137dd2504ac262bdd6c045378394090"}, ] [package.dependencies] @@ -5228,4 +5333,4 @@ valkey = ["valkey-glide"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4.0.0" -content-hash = "08e37143f0927393aa997ebc6fe2a3324415f29d9086f6ba4f8d3a0815db7e42" +content-hash = "368940a68ae8b3bbb72ab67bbb91e4da4170e07a7faf28011343cfcb809ce84a" diff --git a/pyproject.toml b/pyproject.toml index 31ca7daccbe..0510319e5f8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -116,7 +116,7 @@ types-python-dateutil = "^2.8.19.6" aws-cdk-aws-appsync-alpha = "^2.59.0a0" httpx = ">=0.23.3,<0.29.0" sentry-sdk = ">=1.22.2,<3.0.0" -ruff = ">=0.5.1,<0.15.20" +ruff = ">=0.5.1,<0.16.5" retry2 = "^0.9.5" pytest-socket = ">=0.6,<0.9" types-redis = "^4.6.0.7" diff --git a/ruff.toml b/ruff.toml index 6761e206cdc..1bdb7ffa4ae 100644 --- a/ruff.toml +++ b/ruff.toml @@ -33,6 +33,7 @@ lint.select = [ lint.ignore = [ "W291", # https://beta.ruff.rs/docs/rules/trailing-whitespace/ "PLR0913", # https://beta.ruff.rs/docs/rules/too-many-arguments/ + "PLR0917", # https://docs.astral.sh/ruff/rules/too-many-positional-arguments/ "PLR2004", #https://beta.ruff.rs/docs/rules/magic-value-comparison/ "PLW0603", #https://beta.ruff.rs/docs/rules/global-statement/ "B904", # raise-without-from-inside-except - disabled temporarily @@ -44,7 +45,6 @@ lint.ignore = [ "UP006", "UP007", "UP035", - "UP045", ] # Exclude files and directories diff --git a/tests/e2e/utils/data_fetcher/common.py b/tests/e2e/utils/data_fetcher/common.py index 1300daa55aa..61a56386251 100644 --- a/tests/e2e/utils/data_fetcher/common.py +++ b/tests/e2e/utils/data_fetcher/common.py @@ -2,7 +2,7 @@ import time from concurrent.futures import Future, ThreadPoolExecutor from datetime import datetime -from typing import List, Optional, Tuple +from typing import List, Tuple import boto3 import requests @@ -18,8 +18,8 @@ class GetLambdaResponseOptions(BaseModel): lambda_arn: str - payload: Optional[str] = None - client: Optional[LambdaClient] = None + payload: str | None = None + client: LambdaClient | None = None raise_on_error: bool = True model_config = ConfigDict( @@ -29,8 +29,8 @@ class GetLambdaResponseOptions(BaseModel): def get_lambda_response( lambda_arn: str, - payload: Optional[str] = None, - client: Optional[LambdaClient] = None, + payload: str | None = None, + client: LambdaClient | None = None, raise_on_error: bool = True, ) -> GetLambdaResponse: """Invoke function synchronously @@ -39,9 +39,9 @@ def get_lambda_response( ---------- lambda_arn : str Lambda function ARN to invoke - payload : Optional[str], optional + payload : str | None, optional JSON payload for Lambda invocation, by default None - client : Optional[LambdaClient], optional + client : LambdaClient | None, optional Boto3 Lambda SDK client, by default None raise_on_error : bool, optional Whether to raise exception upon invocation error, by default True diff --git a/tests/e2e/utils/data_fetcher/logs.py b/tests/e2e/utils/data_fetcher/logs.py index dc036cba36e..eaa783fbba5 100644 --- a/tests/e2e/utils/data_fetcher/logs.py +++ b/tests/e2e/utils/data_fetcher/logs.py @@ -1,6 +1,6 @@ import json from datetime import datetime -from typing import List, Optional, Union +from typing import Any, List, Union import boto3 from mypy_boto3_logs.client import CloudWatchLogsClient @@ -14,12 +14,12 @@ class Log(BaseModel, extra="allow"): message: Union[dict, str] timestamp: str service: str - cold_start: Optional[bool] = None - function_name: Optional[str] = None - function_memory_size: Optional[str] = None - function_arn: Optional[str] = None - function_request_id: Optional[str] = None - xray_trace_id: Optional[str] = None + cold_start: bool | None = None + function_name: str | None = None + function_memory_size: str | None = None + function_arn: str | None = None + function_request_id: str | None = None + xray_trace_id: str | None = None class LogFetcher: @@ -27,8 +27,8 @@ def __init__( self, function_name: str, start_time: datetime, - log_client: Optional[CloudWatchLogsClient] = None, - filter_expression: Optional[str] = None, + log_client: CloudWatchLogsClient | None = None, + filter_expression: str | None = None, minimum_log_entries: int = 1, ): """Fetch and expose Powertools for AWS Lambda (Python) Logger logs from CloudWatch Logs @@ -39,9 +39,9 @@ def __init__( Name of Lambda function to fetch logs for start_time : datetime Start date range to filter traces - log_client : Optional[CloudWatchLogsClient], optional + log_client : CloudWatchLogsClient | None, optional Amazon CloudWatch Logs Client, by default boto3.client('logs) - filter_expression : Optional[str], optional + filter_expression : str | None, optional CloudWatch Logs Filter Pattern expression, by default "message" minimum_log_entries: int Minimum number of log entries to be retrieved before exhausting retry attempts @@ -54,14 +54,14 @@ def __init__( self.minimum_log_entries = minimum_log_entries self.logs: List[Log] = self._get_logs() - def get_log(self, key: str, value: Optional[any] = None) -> List[Log]: + def get_log(self, key: str, value: Any | None = None) -> List[Log]: """Get logs based on key or key and value Parameters ---------- key : str Log key name - value : Optional[any], optional + value : Any | None, optional Log value, by default None Returns @@ -132,8 +132,8 @@ def get_logs( function_name: str, start_time: datetime, minimum_log_entries: int = 1, - filter_expression: Optional[str] = None, - log_client: Optional[CloudWatchLogsClient] = None, + filter_expression: str | None = None, + log_client: CloudWatchLogsClient | None = None, ) -> LogFetcher: """_summary_ @@ -145,9 +145,9 @@ def get_logs( Start date range to filter traces minimum_log_entries : int Minimum number of log entries to be retrieved before exhausting retry attempts - log_client : Optional[CloudWatchLogsClient], optional + log_client : CloudWatchLogsClient | None, optional Amazon CloudWatch Logs Client, by default boto3.client('logs) - filter_expression : Optional[str], optional + filter_expression : str | None, optional CloudWatch Logs Filter Pattern expression, by default "message" Returns diff --git a/tests/e2e/utils/data_fetcher/traces.py b/tests/e2e/utils/data_fetcher/traces.py index f8b364fc97c..4309fa0d520 100644 --- a/tests/e2e/utils/data_fetcher/traces.py +++ b/tests/e2e/utils/data_fetcher/traces.py @@ -1,6 +1,6 @@ import json from datetime import datetime, timedelta -from typing import TYPE_CHECKING, Any, Dict, Generator, List, Optional +from typing import TYPE_CHECKING, Any, Dict, Generator, List import boto3 from botocore.paginate import PageIterator @@ -17,10 +17,10 @@ class TraceSubsegment(BaseModel): name: str start_time: float end_time: float - aws: Optional[dict] = None - subsegments: Optional[List["TraceSubsegment"]] = None - annotations: Optional[Dict[str, Any]] = None - metadata: Optional[Dict[str, Dict[str, Any]]] = None + aws: dict | None = None + subsegments: List["TraceSubsegment"] | None = None + annotations: Dict[str, Any] | None = None + metadata: Dict[str, Dict[str, Any]] | None = None class TraceDocument(BaseModel): @@ -29,10 +29,10 @@ class TraceDocument(BaseModel): start_time: float end_time: float trace_id: str - parent_id: Optional[str] = None + parent_id: str | None = None aws: Dict origin: str - subsegments: Optional[List[TraceSubsegment]] = None + subsegments: List[TraceSubsegment] | None = None class TraceFetcher: @@ -42,11 +42,11 @@ def __init__( self, filter_expression: str, start_date: datetime, - end_date: Optional[datetime] = None, - xray_client: Optional[XRayClient] = None, - exclude_segment_name: Optional[List[str]] = None, - resource_name: Optional[List[str]] = None, - origin: Optional[List[str]] = None, + end_date: datetime | None = None, + xray_client: XRayClient | None = None, + exclude_segment_name: List[str] | None = None, + resource_name: List[str] | None = None, + origin: List[str] | None = None, minimum_traces: int = 1, ): """Fetch and expose traces from X-Ray based on parameters @@ -67,15 +67,15 @@ def __init__( see: https://docs.aws.amazon.com/xray/latest/devguide/xray-console-filters.html start_date : datetime Start date range to filter traces - end_date : Optional[datetime], optional + end_date : datetime | None, optional End date range to filter traces, by default 5 minutes past start_date - xray_client : Optional[XRayClient], optional + xray_client : XRayClient | None, optional AWS X-Ray SDK Client, by default boto3.client('xray') - exclude_segment_name : Optional[List[str]], optional + exclude_segment_name : List[str] | None, optional Name of segments to exclude, by default ["Initialization", "Invocation", "Overhead"] - resource_name : Optional[List[str]], optional + resource_name : List[str] | None, optional Name of resource to filter traces (e.g., function name), by default None - origin : Optional[List[str]], optional + origin : List[str] | None, optional Trace origin name to filter traces, by default ["AWS::Lambda::Function"] minimum_traces : int Minimum number of traces to be retrieved before exhausting retry attempts @@ -106,7 +106,7 @@ def __init__( self.trace_documents = self._get_trace_documents(trace_ids) self.subsegments = self._get_subsegments() - def get_annotation(self, key: str, value: Optional[any] = None) -> List: + def get_annotation(self, key: str, value: Any | None = None) -> List: return [ annotation for annotation in self.annotations @@ -223,11 +223,11 @@ def _get_trace_documents(self, trace_ids: List[str]) -> Dict[str, TraceDocument] def get_traces( filter_expression: str, start_date: datetime, - end_date: Optional[datetime] = None, - xray_client: Optional[XRayClient] = None, - exclude_segment_name: Optional[List[str]] = None, - resource_name: Optional[List[str]] = None, - origin: Optional[List[str]] = None, + end_date: datetime | None = None, + xray_client: XRayClient | None = None, + exclude_segment_name: List[str] | None = None, + resource_name: List[str] | None = None, + origin: List[str] | None = None, minimum_traces: int = 1, ) -> TraceFetcher: """Fetch traces from AWS X-Ray @@ -239,15 +239,15 @@ def get_traces( see: https://docs.aws.amazon.com/xray/latest/devguide/xray-console-filters.html start_date : datetime Start date range to filter traces - end_date : Optional[datetime], optional + end_date : datetime | None, optional End date range to filter traces, by default 5 minutes past start_date - xray_client : Optional[XRayClient], optional + xray_client : XRayClient | None, optional AWS X-Ray SDK Client, by default boto3.client('xray') - exclude_segment_name : Optional[List[str]], optional + exclude_segment_name : List[str] | None, optional Name of segments to exclude, by default ["Initialization", "Invocation", "Overhead"] - resource_name : Optional[List[str]], optional + resource_name : List[str] | None, optional Name of resource to filter traces (e.g., function name), by default None - origin : Optional[List[str]], optional + origin : List[str] | None, optional Trace origin name to filter traces, by default ["AWS::Lambda::Function"] minimum_traces : int Minimum number of traces to be retrieved before exhausting retry attempts diff --git a/tests/functional/batch/_pydantic/sample_models.py b/tests/functional/batch/_pydantic/sample_models.py index c2912b3f8a3..d3974ccce82 100644 --- a/tests/functional/batch/_pydantic/sample_models.py +++ b/tests/functional/batch/_pydantic/sample_models.py @@ -1,5 +1,5 @@ import json -from typing import Dict, Optional +from typing import Dict from pydantic import field_validator @@ -44,8 +44,8 @@ def transform_message_to_dict(cls, value: Dict[Literal["S"], str]): class OrderDynamoDBChangeRecord(DynamoDBStreamChangedRecordModel): - NewImage: Optional[OrderDynamoDB] = None - OldImage: Optional[OrderDynamoDB] = None + NewImage: OrderDynamoDB | None = None + OldImage: OrderDynamoDB | None = None class OrderDynamoDBRecord(DynamoDBStreamRecordModel): diff --git a/tests/functional/batch/_pydantic/test_utilities_batch_pydantic.py b/tests/functional/batch/_pydantic/test_utilities_batch_pydantic.py index 382cbdb0335..1e6a0452d2a 100644 --- a/tests/functional/batch/_pydantic/test_utilities_batch_pydantic.py +++ b/tests/functional/batch/_pydantic/test_utilities_batch_pydantic.py @@ -1,7 +1,7 @@ import json import uuid from random import randint -from typing import Any, Awaitable, Callable, Dict, Optional +from typing import Any, Awaitable, Callable, Dict import pytest from pydantic import BaseModel, field_validator @@ -311,8 +311,8 @@ def transform_message_to_dict(cls, value: Dict[Literal["S"], str]): return json.loads(value) class OrderDynamoDBChangeRecord(DynamoDBStreamChangedRecordModel): - NewImage: Optional[OrderDynamoDB] = None - OldImage: Optional[OrderDynamoDB] = None + NewImage: OrderDynamoDB | None = None + OldImage: OrderDynamoDB | None = None class OrderDynamoDBRecord(DynamoDBStreamRecordModel): dynamodb: OrderDynamoDBChangeRecord @@ -355,8 +355,8 @@ def transform_message_to_dict(cls, value: Dict[Literal["S"], str]): return json.loads(value) class OrderDynamoDBChangeRecord(DynamoDBStreamChangedRecordModel): - NewImage: Optional[OrderDynamoDB] = None - OldImage: Optional[OrderDynamoDB] = None + NewImage: OrderDynamoDB | None = None + OldImage: OrderDynamoDB | None = None class OrderDynamoDBRecord(DynamoDBStreamRecordModel): dynamodb: OrderDynamoDBChangeRecord diff --git a/tests/functional/event_handler/_pydantic/test_bedrock_agent.py b/tests/functional/event_handler/_pydantic/test_bedrock_agent.py index 4367a94f49d..90e9e69790b 100644 --- a/tests/functional/event_handler/_pydantic/test_bedrock_agent.py +++ b/tests/functional/event_handler/_pydantic/test_bedrock_agent.py @@ -1,6 +1,6 @@ import json from functools import partial -from typing import Any, Dict, Optional +from typing import Any, Dict import pytest from typing_extensions import Annotated @@ -192,7 +192,7 @@ def test_openapi_schema_for_pydanticv2(openapi30_schema): # WHEN we have a simple handler @app.get("/", description="Testing") - def handler() -> Optional[Dict]: + def handler() -> Dict | None: pass # WHEN we get the schema @@ -336,7 +336,7 @@ def test_bedrock_resolver_with_openapi_extensions(): # WHEN we have a simple handler with openapi extension @app.get("/", description="Testing", openapi_extensions={"x-requireConfirmation": "ENABLED"}) - def handler() -> Optional[Dict]: + def handler() -> Dict | None: pass # WHEN we get the schema diff --git a/tests/functional/event_handler/_pydantic/test_openapi_params.py b/tests/functional/event_handler/_pydantic/test_openapi_params.py index 40722bb838b..b9426bf4da7 100644 --- a/tests/functional/event_handler/_pydantic/test_openapi_params.py +++ b/tests/functional/event_handler/_pydantic/test_openapi_params.py @@ -1,7 +1,7 @@ import json from dataclasses import dataclass from datetime import datetime -from typing import List, Literal, Optional, Tuple +from typing import List, Literal, Tuple import pytest from pydantic import BaseModel, Field @@ -34,7 +34,7 @@ def test_openapi_pydantic_query_params(): class QueryParams(BaseModel): limit: int = Field(default=10, ge=1, le=100, description="Number of items to return") offset: int = Field(default=0, ge=0, description="Number of items to skip") - search: Optional[str] = Field(default=None, description="Search term") + search: str | None = Field(default=None, description="Search term") @app.get("/search") def search_handler(params: Annotated[QueryParams, Query()]): @@ -82,7 +82,7 @@ def test_openapi_pydantic_header_params(): class HeaderParams(BaseModel): authorization: str = Field(description="Authorization token") user_agent: str = Field(default="PowerTools/1.0", description="User agent") - language: Optional[str] = Field(default=None, alias="accept-language", description="Language preference") + language: str | None = Field(default=None, alias="accept-language", description="Language preference") @app.get("/protected") def protected_handler(headers: Annotated[HeaderParams, Header()]): @@ -941,7 +941,7 @@ def test_openapi_form_parameter_edge_cases(): @app.post("/form-edge-cases") def form_edge_cases( required_field: Annotated[str, Form(description="Required field")], - optional_field: Annotated[Optional[str], Form(description="Optional field")] = None, + optional_field: Annotated[str | None, Form(description="Optional field")] = None, field_with_default: Annotated[str, Form(description="Field with default")] = "default_value", ): return {"required": required_field, "optional": optional_field, "default": field_with_default} @@ -1034,7 +1034,7 @@ def test_openapi_pydantic_required_vs_optional(): class QueryParams(BaseModel): required_field: str = Field(description="Required field") optional_with_default: str = Field(default="default", description="Optional with default") - optional_nullable: Optional[str] = Field(default=None, description="Optional nullable") + optional_nullable: str | None = Field(default=None, description="Optional nullable") @app.get("/test") def test_handler(params: Annotated[QueryParams, Query()]): diff --git a/tests/functional/event_handler/_pydantic/test_openapi_responses.py b/tests/functional/event_handler/_pydantic/test_openapi_responses.py index dccfae3e28d..c00b4e00462 100644 --- a/tests/functional/event_handler/_pydantic/test_openapi_responses.py +++ b/tests/functional/event_handler/_pydantic/test_openapi_responses.py @@ -1,5 +1,5 @@ from secrets import randbelow -from typing import Optional, Union +from typing import Union from pydantic import BaseModel @@ -325,7 +325,7 @@ def test_openapi_response_examples_preserved_with_model(): class UserResponse(BaseModel): id: int name: str - email: Optional[str] = None + email: str | None = None @app.get( "/", diff --git a/tests/functional/event_handler/_pydantic/test_openapi_schema_pydantic_v2.py b/tests/functional/event_handler/_pydantic/test_openapi_schema_pydantic_v2.py index d25811d24ae..6f4b89e47cc 100644 --- a/tests/functional/event_handler/_pydantic/test_openapi_schema_pydantic_v2.py +++ b/tests/functional/event_handler/_pydantic/test_openapi_schema_pydantic_v2.py @@ -1,6 +1,6 @@ import json import warnings -from typing import Literal, Optional +from typing import Literal import pytest from pydantic import BaseModel, Field, computed_field @@ -52,7 +52,7 @@ def test_openapi_3_1_complex_handler(openapi31_schema): # GIVEN a complex pydantic model class TodoAttributes(BaseModel): userId: int - id_: Optional[int] = Field(alias="id", default=None) + id_: int | None = Field(alias="id", default=None) title: str completed: bool diff --git a/tests/functional/event_handler/_pydantic/test_openapi_serialization.py b/tests/functional/event_handler/_pydantic/test_openapi_serialization.py index ef5c8ddd938..9bad2c61422 100644 --- a/tests/functional/event_handler/_pydantic/test_openapi_serialization.py +++ b/tests/functional/event_handler/_pydantic/test_openapi_serialization.py @@ -1,6 +1,6 @@ import json from dataclasses import dataclass -from typing import Dict, Optional, Set +from typing import Dict, Set import pytest from pydantic import BaseModel @@ -81,7 +81,7 @@ class Model(BaseModel): age: int @app.get("/valid_optional") - def handler_valid_optional() -> Optional[Model]: + def handler_valid_optional() -> Model | None: return Model(name="John", age=30) # WHEN returning a valid model for an Optional type diff --git a/tests/functional/event_handler/_pydantic/test_openapi_validation_middleware.py b/tests/functional/event_handler/_pydantic/test_openapi_validation_middleware.py index aee94e80b14..ec14c14fa08 100644 --- a/tests/functional/event_handler/_pydantic/test_openapi_validation_middleware.py +++ b/tests/functional/event_handler/_pydantic/test_openapi_validation_middleware.py @@ -5,7 +5,7 @@ from dataclasses import dataclass from enum import Enum from pathlib import PurePath -from typing import Any, Dict, List, Literal, Optional, Tuple, Union +from typing import Any, Dict, List, Literal, Tuple, Union import pytest from pydantic import ( @@ -88,7 +88,7 @@ def test_validate_pydantic_query_params(gw_event): class QueryParams(BaseModel): limit: int = Field(default=10, ge=1, le=100, description="Number of items") - search: Optional[str] = Field(default=None, description="Search term") + search: str | None = Field(default=None, description="Search term") @app.get("/search") def search_handler(params: Annotated[QueryParams, Query()]): @@ -1777,7 +1777,7 @@ class Model(BaseModel): age: int @app.get("/none_allowed") - def handler_none_allowed() -> Optional[Model]: + def handler_none_allowed() -> Model | None: return None # WHEN returning None for an Optional type @@ -3123,15 +3123,15 @@ def _post_json(app, path, payload): return result["statusCode"], json.loads(result["body"]) -# ---------- Optional[List[Model]] ---------- +# ---------- List[Model] | None ---------- def test_optional_list_body_with_list(): - """Optional[List[Model]] must preserve the full list.""" + """List[Model] | None must preserve the full list.""" app = APIGatewayRestResolver(enable_validation=True) @app.post("/items") - def handler(items: Annotated[Optional[List[_Item]], Body()]) -> Dict[str, Any]: + def handler(items: Annotated[List[_Item] | None, Body()]) -> Dict[str, Any]: assert isinstance(items, list) return {"count": len(items)} @@ -3141,11 +3141,11 @@ def handler(items: Annotated[Optional[List[_Item]], Body()]) -> Dict[str, Any]: def test_optional_list_body_with_none(): - """Optional[List[Model]] must accept a null body gracefully.""" + """List[Model] | None must accept a null body gracefully.""" app = APIGatewayRestResolver(enable_validation=True) @app.post("/items") - def handler(items: Annotated[Optional[List[_Item]], Body()] = None) -> Dict[str, Any]: + def handler(items: Annotated[List[_Item] | None, Body()] = None) -> Dict[str, Any]: return {"received_none": items is None} status, body = _post_json(app, "/items", None) @@ -3153,15 +3153,15 @@ def handler(items: Annotated[Optional[List[_Item]], Body()] = None) -> Dict[str, assert body["received_none"] is True -# ---------- Optional[Union[Model, List[Model]]] ---------- +# ---------- Union[Model, List[Model]] | None ---------- def test_optional_union_model_or_list_with_list(): - """Optional[Union[Model, List[Model]]] — send list, get full list.""" + """Union[Model, List[Model]] | None — send list, get full list.""" app = APIGatewayRestResolver(enable_validation=True) @app.post("/items") - def handler(items: Annotated[Optional[Union[_Item, List[_Item]]], Body()]) -> Dict[str, Any]: + def handler(items: Annotated[Union[_Item, List[_Item]] | None, Body()]) -> Dict[str, Any]: assert isinstance(items, list) return {"count": len(items)} @@ -3171,11 +3171,11 @@ def handler(items: Annotated[Optional[Union[_Item, List[_Item]]], Body()]) -> Di def test_optional_union_model_or_list_with_single(): - """Optional[Union[Model, List[Model]]] — send single obj, get single obj.""" + """Union[Model, List[Model]] | None — send single obj, get single obj.""" app = APIGatewayRestResolver(enable_validation=True) @app.post("/items") - def handler(items: Annotated[Optional[Union[_Item, List[_Item]]], Body()]) -> Dict[str, Any]: + def handler(items: Annotated[Union[_Item, List[_Item]] | None, Body()]) -> Dict[str, Any]: assert not isinstance(items, list) return {"name": items.name} @@ -3185,11 +3185,11 @@ def handler(items: Annotated[Optional[Union[_Item, List[_Item]]], Body()]) -> Di def test_optional_union_model_or_list_with_none(): - """Optional[Union[Model, List[Model]]] — send null, get None.""" + """Union[Model, List[Model]] | None — send null, get None.""" app = APIGatewayRestResolver(enable_validation=True) @app.post("/items") - def handler(items: Annotated[Optional[Union[_Item, List[_Item]]], Body()] = None) -> Dict[str, Any]: + def handler(items: Annotated[Union[_Item, List[_Item]] | None, Body()] = None) -> Dict[str, Any]: return {"is_none": items is None} status, body = _post_json(app, "/items", None) @@ -3288,11 +3288,11 @@ def handler(data: Annotated[Union[str, List[Dict[str, Any]]], Body()]) -> Dict[s def test_optional_rootmodel_list_body(): - """Optional[RootModel[List[Model]]] — list must not be truncated.""" + """RootModel[List[Model]] | None — list must not be truncated.""" app = APIGatewayRestResolver(enable_validation=True) @app.post("/items") - def handler(items: Annotated[Optional[_ItemCollection], Body()]) -> Dict[str, Any]: + def handler(items: Annotated[_ItemCollection | None, Body()]) -> Dict[str, Any]: return {"count": len(items.root)} status, body = _post_json(app, "/items", _THREE_ITEMS) diff --git a/tests/functional/idempotency/_boto3/test_idempotency.py b/tests/functional/idempotency/_boto3/test_idempotency.py index e5916dba0fa..56b317a9b5a 100644 --- a/tests/functional/idempotency/_boto3/test_idempotency.py +++ b/tests/functional/idempotency/_boto3/test_idempotency.py @@ -2,7 +2,7 @@ import dataclasses import datetime import warnings -from typing import Any, Optional +from typing import Any from unittest.mock import MagicMock, Mock import jmespath @@ -1046,6 +1046,10 @@ def test_is_missing_idempotency_key(): assert BasePersistenceLayer.is_missing_idempotency_key((None, None)) # GIVEN a dict of Nones THEN is_missing_idempotency_key is True assert BasePersistenceLayer.is_missing_idempotency_key({None: None}) + # GIVEN a dict with all-None values THEN is_missing_idempotency_key is True + assert BasePersistenceLayer.is_missing_idempotency_key({"user": None, "order": None}) + # GIVEN a dict with a non-None value THEN is_missing_idempotency_key is False + assert BasePersistenceLayer.is_missing_idempotency_key({"user": "abc"}) is False # GIVEN True THEN is_missing_idempotency_key is False assert BasePersistenceLayer.is_missing_idempotency_key(True) is False @@ -1114,6 +1118,19 @@ def test_raise_on_no_idempotency_key( assert "No data found to create a hashed idempotency_key" in str(excinfo.value) +def test_raise_on_no_idempotency_key_for_dict_jmespath(persistence_store: DynamoDBPersistenceLayer): + # GIVEN a dict multi-select expression whose values are missing + idempotency_config = IdempotencyConfig( + event_key_jmespath="{user: headers.user_id, order: body.order_id}", + raise_on_no_idempotency_key=True, + ) + persistence_store.configure(idempotency_config) + + # WHEN extracting the idempotency key THEN raise IdempotencyKeyError + with pytest.raises(IdempotencyKeyError, match="No data found to create a hashed idempotency_key"): + persistence_store._get_hashed_idempotency_key({"headers": {}, "body": {}}) + + @pytest.mark.parametrize( "idempotency_config", [ @@ -2086,7 +2103,7 @@ class PaymentOutput: config=config, output_serializer=output_serializer, ) - def collect_payment(payment: PaymentInput) -> Optional[PaymentOutput]: + def collect_payment(payment: PaymentInput) -> PaymentOutput | None: return PaymentOutput(**dataclasses.asdict(payment)) # WHEN diff --git a/tests/functional/idempotency/_pydantic/test_idempotency_with_pydantic.py b/tests/functional/idempotency/_pydantic/test_idempotency_with_pydantic.py index f8e3debbc30..b5decebafbe 100644 --- a/tests/functional/idempotency/_pydantic/test_idempotency_with_pydantic.py +++ b/tests/functional/idempotency/_pydantic/test_idempotency_with_pydantic.py @@ -1,5 +1,3 @@ -from typing import Optional - import pytest from pydantic import BaseModel @@ -252,7 +250,7 @@ class PaymentOutput(BaseModel): config=config, output_serializer=output_serializer, ) - def collect_payment(payment: PaymentInput) -> Optional[PaymentOutput]: + def collect_payment(payment: PaymentInput) -> PaymentOutput | None: return PaymentOutput(**payment.dict()) # WHEN diff --git a/tests/functional/idempotency/_redis/test_redis_layer.py b/tests/functional/idempotency/_redis/test_redis_layer.py index 22c3b9a6d83..6adb97a64a4 100644 --- a/tests/functional/idempotency/_redis/test_redis_layer.py +++ b/tests/functional/idempotency/_redis/test_redis_layer.py @@ -3,6 +3,7 @@ import datetime import json import time as t +from threading import Event, Lock as ThreadLock, Thread from unittest import mock import pytest @@ -26,6 +27,7 @@ STATUS_CONSTANTS, DataRecord, ) +from aws_lambda_powertools.utilities.idempotency.persistence.cache import CachePersistenceLayer from aws_lambda_powertools.utilities.idempotency.persistence.redis import ( RedisCachePersistenceLayer, ) @@ -198,6 +200,16 @@ def valid_record(): ) +@pytest.fixture +def in_progress_record_missing_expiry(): + return DataRecord( + idempotency_key="test_orphan_key", + status=STATUS_CONSTANTS["INPROGRESS"], + expiry_timestamp=int(datetime.datetime.now().timestamp()) + 60, + in_progress_expiry_timestamp=None, + ) + + @mock.patch("aws_lambda_powertools.utilities.idempotency.persistence.redis.redis", MockRedis()) def test_redis_connection_standalone(): # when RedisCachePersistenceLayer is init with the following params @@ -303,6 +315,73 @@ def test_redis_orphan_record_lock(orphan_record, valid_record): ) +@mock.patch("aws_lambda_powertools.utilities.idempotency.persistence.redis.redis", MockRedis()) +def test_redis_in_progress_record_missing_expiry_is_not_treated_as_orphan(in_progress_record_missing_expiry): + layer = RedisCachePersistenceLayer(host="host") + layer._put_in_progress_record(in_progress_record_missing_expiry) + + contender = DataRecord( + idempotency_key=in_progress_record_missing_expiry.idempotency_key, + status=STATUS_CONSTANTS["INPROGRESS"], + expiry_timestamp=in_progress_record_missing_expiry.expiry_timestamp + 60, + in_progress_expiry_timestamp=None, + ) + + with pytest.raises(IdempotencyItemAlreadyExistsError): + layer._put_in_progress_record(contender) + + stored_record = layer._get_record(in_progress_record_missing_expiry.idempotency_key) + assert stored_record.status == STATUS_CONSTANTS["INPROGRESS"] + assert stored_record.expiry_timestamp == in_progress_record_missing_expiry.expiry_timestamp + + +@pytest.mark.filterwarnings("ignore:Couldn't determine the remaining time left") +def test_idempotent_function_blocks_concurrent_invocation_without_lambda_context(): + layer = CachePersistenceLayer(client=MockRedis(host="localhost")) + first_invocation_started = Event() + release_first_invocation = Event() + execution_lock = ThreadLock() + execution_count = 0 + first_result = [] + first_errors = [] + + @idempotent_function(data_keyword_argument="record", persistence_store=layer) + def process(record): + nonlocal execution_count + with execution_lock: + execution_count += 1 + current_execution = execution_count + + if current_execution == 1: + first_invocation_started.set() + if not release_first_invocation.wait(timeout=5): + raise TimeoutError("Timed out waiting to release the first invocation") + + return {"execution": current_execution} + + def invoke_first(): + try: + first_result.append(process(record={"id": "same"})) + except Exception as exc: + first_errors.append(exc) + + first_invocation = Thread(target=invoke_first) + first_invocation.start() + assert first_invocation_started.wait(timeout=2) + + try: + with pytest.raises(IdempotencyAlreadyInProgressError): + process(record={"id": "same"}) + finally: + release_first_invocation.set() + first_invocation.join(timeout=5) + + assert not first_invocation.is_alive() + assert first_errors == [] + assert first_result == [{"execution": 1}] + assert execution_count == 1 + + @mock.patch("aws_lambda_powertools.utilities.idempotency.persistence.redis.redis", MockRedis()) def test_redis_error_in_progress(valid_record): layer = RedisCachePersistenceLayer(host="host", mode="standalone") diff --git a/tests/functional/idempotency/utils.py b/tests/functional/idempotency/utils.py index 2e1ee4ab821..c6b3ee9b1a0 100644 --- a/tests/functional/idempotency/utils.py +++ b/tests/functional/idempotency/utils.py @@ -1,6 +1,6 @@ import hashlib import json -from typing import Any, Dict, Optional +from typing import Any, Dict from botocore import stub from pytest import FixtureRequest @@ -88,7 +88,7 @@ def build_idempotency_put_item_response_stub( expiration: int, status: str, request: FixtureRequest, - validation_data: Optional[Any], + validation_data: Any | None, ): response = { "Item": { diff --git a/tests/unit/parser/_pydantic/schemas.py b/tests/unit/parser/_pydantic/schemas.py index 0713924c486..2565d649ee9 100644 --- a/tests/unit/parser/_pydantic/schemas.py +++ b/tests/unit/parser/_pydantic/schemas.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import List from pydantic import BaseModel @@ -21,8 +21,8 @@ class MyDynamoBusiness(BaseModel): class MyDynamoScheme(DynamoDBStreamChangedRecordModel): - NewImage: Optional[MyDynamoBusiness] = None - OldImage: Optional[MyDynamoBusiness] = None + NewImage: MyDynamoBusiness | None = None + OldImage: MyDynamoBusiness | None = None class MyDynamoDBStreamRecordModel(DynamoDBStreamRecordModel):