Skip to content

Commit 02ebf37

Browse files
authored
Merge branch 'develop' into add-cfn-schem-fetcher
2 parents 6ca30be + f202776 commit 02ebf37

6 files changed

Lines changed: 38 additions & 19 deletions

File tree

requirements/base.txt

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
boto3>=1.34.0,<2.0.0
2-
jsonschema<5,>=3.2 # TODO: evaluate risk of removing jsonschema 3.x support
2+
jsonschema<5,>=4.23
33
typing_extensions>=4.4 # 3.8 doesn't have Required, TypeGuard and ParamSpec
44

55
# resource validation & schema generation
6-
# 1.10.15 and 1.10.17 included breaking change from pydantic, more info: https://github.com/aws/serverless-application-model/issues/3617
7-
pydantic>=1.8,<3,!=1.10.15,!=1.10.17
6+
# we should remove support for Python 3.8 soon (and 3.9), but supporting it for now
7+
pydantic>=2.10.6; python_version>="3.8"
8+
pydantic~=2.12.5; python_version>="3.9"

requirements/dev.txt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,9 @@ black==24.3.0
2323
ruamel.yaml==0.17.21 # It can parse yaml while perserving comments
2424

2525
# type check
26-
mypy~=1.3.0
26+
mypy~=1.10.1
2727

2828
# types
2929
boto3-stubs[appconfig,serverlessrepo]>=1.34.0,<2.0.0
3030
types-PyYAML~=6.0
3131
types-jsonschema~=3.2
32-
33-
# CloudFormation CLI tools
34-
cloudformation-cli>=0.2.39,<0.3.0

samtranslator/model/__init__.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -824,15 +824,14 @@ def resolve_resource_type(self, resource_dict: Dict[str, Any]) -> Any:
824824

825825

826826
class ResourceResolver:
827-
def __init__(self, resources: Dict[str, Any]) -> None:
827+
def __init__(self, resources: Dict[str, Dict[str, Any]]) -> None:
828828
"""
829829
Instantiate the resolver
830830
:param dict resources: Map of resource
831831
"""
832832

833833
if not isinstance(resources, dict):
834834
raise TypeError("'Resources' is either null or not a valid dictionary.")
835-
836835
self.resources = resources
837836

838837
def get_all_resources(self) -> Dict[str, Any]:
@@ -850,7 +849,6 @@ def get_resource_by_logical_id(self, _input: str) -> Optional[Dict[str, Any]]:
850849
"""
851850
if not isinstance(_input, str):
852851
raise TypeError(f"Invalid logical ID '{_input}'. Expected a string.")
853-
854852
return self.resources.get(_input, None)
855853

856854

samtranslator/model/apigateway.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -522,7 +522,7 @@ def _get_identity_header(self) -> Optional[str]:
522522
if not self.identity or not self.identity.get("Header"):
523523
return "Authorization"
524524

525-
return self.identity.get("Header")
525+
return self.identity.get("Header") # type: ignore[no-any-return]
526526

527527
def _get_reauthorize_every(self) -> Optional[PassThrough]:
528528
if not self.identity:

samtranslator/model/sam_resources.py

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import copy
44
import re
5+
import sys
56
from contextlib import suppress
7+
from types import ModuleType
68
from typing import Any, Callable, Dict, List, Literal, Optional, Tuple, Union, cast
79

810
import samtranslator.model.eventsources
@@ -34,11 +36,19 @@
3436
SyncConfigType,
3537
UserPoolConfigType,
3638
)
37-
from samtranslator.internal.schema_source import (
38-
aws_serverless_capacity_provider,
39-
aws_serverless_function,
40-
aws_serverless_graphqlapi,
41-
)
39+
40+
# Pydantic 1 doesn't support Python 3.14 so these imports will fail until we migrate to v2
41+
try:
42+
from samtranslator.internal.schema_source import (
43+
aws_serverless_capacity_provider,
44+
aws_serverless_function,
45+
aws_serverless_graphqlapi,
46+
)
47+
except RuntimeError: # Pydantic fails when initializing the model classes with a RuntimeError in 3.14
48+
aws_serverless_capacity_provider = cast(ModuleType, None)
49+
aws_serverless_function = cast(ModuleType, None)
50+
aws_serverless_graphqlapi = cast(ModuleType, None)
51+
4252
from samtranslator.internal.schema_source.common import PermissionsType, SamIntrinsicable
4353
from samtranslator.internal.types import GetManagedPolicyMap
4454
from samtranslator.internal.utils.utils import passthrough_value, remove_none_values
@@ -143,6 +153,14 @@
143153
_CONDITION_CHAR_LIMIT = 255
144154

145155

156+
# Utility function to throw an error when using functionality that doesn't work in Python 3.14 (need migration to Pydantic v2)
157+
def check_python_314_compatibility(module: Optional[ModuleType], functionality: str) -> None:
158+
if sys.version_info >= (3, 14) and module is None:
159+
raise RuntimeError(
160+
f"{functionality} functionalities are temporarily not supported when running SAM in Python 3.14"
161+
)
162+
163+
146164
class SamFunction(SamResourceMacro):
147165
"""SAM function macro."""
148166

@@ -788,6 +806,7 @@ def _transform_capacity_provider_config(self) -> Dict[str, Any]:
788806

789807
# Validate CapacityProviderConfig using Pydantic model directly for comprehensive error collection
790808
try:
809+
check_python_314_compatibility(aws_serverless_function, "Capacity Provider")
791810
validated_model = aws_serverless_function.CapacityProviderConfig.parse_obj(self.CapacityProviderConfig)
792811
except Exception as e:
793812
raise InvalidResourceException(self.logical_id, f"Invalid CapacityProviderConfig: {e!s}") from e
@@ -1516,7 +1535,6 @@ class SamCapacityProvider(SamResourceMacro):
15161535
"""
15171536

15181537
resource_type = "AWS::Serverless::CapacityProvider"
1519-
resource_property_schema = aws_serverless_capacity_provider.Properties
15201538
property_types = {
15211539
"CapacityProviderName": Property(False, one_of(IS_STR, IS_DICT)),
15221540
"VpcConfig": Property(True, IS_DICT),
@@ -1549,7 +1567,11 @@ def to_cloudformation(self, **kwargs: Any) -> List[Resource]:
15491567
"""
15501568
Transform the SAM CapacityProvider resource to CloudFormation
15511569
"""
1552-
self.validate_before_transform(schema_class=self.resource_property_schema, collect_all_errors=True)
1570+
check_python_314_compatibility(aws_serverless_capacity_provider, "Capacity Provider")
1571+
self.validate_before_transform(
1572+
schema_class=aws_serverless_capacity_provider.Properties,
1573+
collect_all_errors=True,
1574+
)
15531575

15541576
# Use enhanced validation method with comprehensive error collection
15551577
model = self.validate_properties_and_return_model(
@@ -2657,6 +2679,7 @@ def __init__(
26572679

26582680
@cw_timer
26592681
def to_cloudformation(self, **kwargs: Any) -> List[Resource]:
2682+
check_python_314_compatibility(aws_serverless_graphqlapi, "GraphQLApi")
26602683
model = self.validate_properties_and_return_model(aws_serverless_graphqlapi.Properties)
26612684

26622685
appsync_api, cloudwatch_role, auth_connectors = self._construct_appsync_api_resources(model)

samtranslator/model/stepfunctions/generators.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ def _get_paths_to_intrinsics(self, _input, path=None): # type: ignore[no-untype
396396
else:
397397
return dynamic_value_paths
398398

399-
for key, value in sorted(iterator, key=lambda item: item[0]): # type: ignore[no-any-return]
399+
for key, value in sorted(iterator, key=lambda item: item[0]):
400400
if is_intrinsic(value) or is_dynamic_reference(value):
401401
dynamic_value_paths.append([*path, key])
402402
elif isinstance(value, (dict, list)):

0 commit comments

Comments
 (0)