Skip to content

Commit 1e29fc8

Browse files
authored
Release 1.63.0 (to main) #3067
Release 1.63.0 (to main)
2 parents 1e5b158 + efdc6cb commit 1e29fc8

File tree

160 files changed

+9363
-1144
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

160 files changed

+9363
-1144
lines changed

.cfnlintrc.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,4 @@ ignore_checks:
125125
- E2531 # Deprecated runtime; not relevant for transform tests
126126
- W2531 # EOL runtime; not relevant for transform tests
127127
- E3001 # Invalid or unsupported Type; common in transform tests since they focus on SAM resources
128+
- W2001 # Parameter not used

.github/workflows/build.yml

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ on:
77
- "feat-*"
88
pull_request:
99
workflow_dispatch:
10+
merge_group:
11+
types: [checks_requested]
1012

1113
jobs:
1214
build:
@@ -22,6 +24,7 @@ jobs:
2224
- "3.8"
2325
- "3.9"
2426
- "3.10"
27+
- "3.11"
2528
steps:
2629
- uses: actions/checkout@v3
2730
- uses: actions/setup-python@v4

.github/workflows/check_compatibility.yml

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ name: Check compatibility
22

33
on:
44
pull_request:
5+
merge_group:
6+
types: [checks_requested]
57

68
jobs:
79
check-compatibility:

.github/workflows/codeql.yml

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ on:
1717
pull_request:
1818
# The branches below must be a subset of the branches above
1919
branches: [ "develop" ]
20+
merge_group:
21+
types: [checks_requested]
2022
schedule:
2123
- cron: '43 23 * * 2'
2224

bin/_file_formatter.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def config_additional_args(cls) -> None: # noqa: empty-method-without-abstract-
4545
"""Optionally configure additional args to arg parser."""
4646

4747
def process_file(self, file_path: str) -> None:
48-
with open(file_path, "r", encoding="utf-8") as f:
48+
with open(file_path, encoding="utf-8") as f:
4949
file_str = f.read()
5050
try:
5151
formatted_file_str = self.format_str(file_str)

bin/add_transform_test.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import shutil
77
import subprocess
88
import sys
9+
from copy import deepcopy
910
from pathlib import Path
1011
from typing import Any, Dict
1112

@@ -74,7 +75,7 @@ def replace_aws_partition(partition: str, file_path: str) -> None:
7475
def generate_transform_test_output_files(input_file_path: str, file_basename: str) -> None:
7576
output_file_option = file_basename + ".json"
7677

77-
with open(os.path.join(input_file_path), "r") as f:
78+
with open(os.path.join(input_file_path)) as f:
7879
manifest = yaml_parse(f) # type: ignore[no-untyped-call]
7980

8081
transform_test_output_paths = {
@@ -86,7 +87,8 @@ def generate_transform_test_output_files(input_file_path: str, file_basename: st
8687
for partition, (region, output_path) in transform_test_output_paths.items():
8788
# Set Boto Session Region to guarantee the same hash input as transform tests for API deployment id
8889
ArnGenerator.BOTO_SESSION_REGION_NAME = region
89-
output_fragment = transform(manifest, {}, ManagedPolicyLoader(iam_client))
90+
# Implicit API Plugin may alter input template file, thus passing a copy here.
91+
output_fragment = transform(deepcopy(manifest), {}, ManagedPolicyLoader(iam_client))
9092

9193
if not CLI_OPTIONS.disable_api_configuration and partition != "aws":
9294
output_fragment = add_regional_endpoint_configuration_if_needed(output_fragment)

bin/public_interface.py

+13-3
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,20 @@
1515
import pkgutil
1616
import sys
1717
from pathlib import Path
18-
from typing import Any, Dict, List, NamedTuple, Set, Union
18+
from typing import Any, Dict, List, NamedTuple, Optional, Set, Union
1919

2020
_ARGUMENT_SELF = {"kind": "POSITIONAL_OR_KEYWORD", "name": "self"}
2121

2222

2323
class InterfaceScanner:
24-
def __init__(self) -> None:
24+
def __init__(self, skipped_modules: Optional[List[str]] = None) -> None:
2525
self.signatures: Dict[str, Union[inspect.Signature]] = {}
2626
self.variables: Set[str] = set()
27+
self.skipped_modules: Set[str] = set(skipped_modules or [])
2728

2829
def scan_interfaces_recursively(self, module_name: str) -> None:
30+
if module_name in self.skipped_modules:
31+
return
2932
self._scan_interfaces_in_module(module_name)
3033
for submodule in pkgutil.iter_modules([module_name.replace(".", os.path.sep)]):
3134
submodule_name = module_name + "." + submodule.name
@@ -212,13 +215,20 @@ def main() -> None:
212215
subparsers = parser.add_subparsers(dest="command")
213216
extract = subparsers.add_parser("extract", help="Extract public interfaces")
214217
extract.add_argument("--module", help="The module to extract public interfaces", type=str, default="samtranslator")
218+
extract.add_argument(
219+
"--skipped-module",
220+
help="The modules that should be skipped",
221+
type=str,
222+
nargs="*",
223+
default=["samtranslator.internal"],
224+
)
215225
check = subparsers.add_parser("check", help="Check public interface changes")
216226
check.add_argument("original_json", help="The original public interface JSON file", type=Path)
217227
check.add_argument("new_json", help="The new public interface JSON file", type=Path)
218228
args = parser.parse_args()
219229

220230
if args.command == "extract":
221-
scanner = InterfaceScanner()
231+
scanner = InterfaceScanner(skipped_modules=args.skipped_module)
222232
scanner.scan_interfaces_recursively(args.module)
223233
_print(scanner.signatures, scanner.variables)
224234
elif args.command == "check":

bin/sam-translate.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"--output-template",
4141
help="Location to store resulting CloudFormation template [default: transformed-template.json].",
4242
type=Path,
43-
default=Path("transformed-template.yaml"),
43+
default=Path("transformed-template.json"),
4444
)
4545
parser.add_argument(
4646
"--s3-bucket",
@@ -102,7 +102,7 @@ def package(input_file_path, output_file_path): # type: ignore[no-untyped-def]
102102

103103

104104
def transform_template(input_file_path, output_file_path): # type: ignore[no-untyped-def]
105-
with open(input_file_path, "r") as f:
105+
with open(input_file_path) as f:
106106
sam_template = yaml_parse(f) # type: ignore[no-untyped-call]
107107

108108
try:

integration/combination/test_api_settings.py

+3-8
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
import hashlib
2+
from pathlib import Path
23
from unittest.case import skipIf
34

4-
from integration.config.service_names import REST_API
5-
from integration.helpers.resource import current_region_does_not_support
6-
7-
try:
8-
from pathlib import Path
9-
except ImportError:
10-
from pathlib2 import Path
11-
125
from parameterized import parameterized
136

7+
from integration.config.service_names import REST_API
148
from integration.helpers.base_test import BaseTest
9+
from integration.helpers.resource import current_region_does_not_support
1510

1611

1712
@skipIf(current_region_does_not_support([REST_API]), "Rest API is not supported in this testing region")

integration/combination/test_api_with_authorizer_apikey.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ def verify_authorized_request(
8585
status = response.status_code
8686
if status != expected_status_code:
8787
raise StatusCodeError(
88-
"Request to {} failed with status: {}, expected status: {}".format(url, status, expected_status_code)
88+
f"Request to {url} failed with status: {status}, expected status: {expected_status_code}"
8989
)
9090

9191
if not header_key or not header_value:

integration/combination/test_api_with_authorizers.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ def verify_authorized_request(
444444

445445
if status != expected_status_code:
446446
raise StatusCodeError(
447-
"Request to {} failed with status: {}, expected status: {}".format(url, status, expected_status_code)
447+
f"Request to {url} failed with status: {status}, expected status: {expected_status_code}"
448448
)
449449

450450
if not header_key or not header_value:

integration/combination/test_api_with_cors.py

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class TestApiWithCors(BaseTest):
1515
[
1616
"combination/api_with_cors",
1717
"combination/api_with_cors_openapi",
18+
"combination/api_with_cors_and_apikey",
1819
]
1920
)
2021
def test_cors(self, file_name):

integration/combination/test_function_with_api.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ def test_function_with_api(self):
2828

2929
self.assertTrue(
3030
get_api_policy_expectation in policy,
31-
"{} should be present in policy {}".format(get_api_policy_expectation, policy),
31+
f"{get_api_policy_expectation} should be present in policy {policy}",
3232
)
3333
self.assertTrue(
3434
post_api_policy_expectation in policy,
35-
"{} should be present in policy {}".format(post_api_policy_expectation, policy),
35+
f"{post_api_policy_expectation} should be present in policy {policy}",
3636
)

integration/combination/test_function_with_sns.py

+7-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
@skipIf(current_region_does_not_support([SNS]), "SNS is not supported in this testing region")
99
class TestFunctionWithSns(BaseTest):
1010
def test_function_with_sns_bucket_trigger(self):
11-
self.create_and_verify_stack("combination/function_with_sns")
11+
template_file_path = "combination/function_with_sns"
12+
self.skip_using_service_detector(template_file_path)
13+
self.create_and_verify_stack(template_file_path)
1214

1315
sns_client = self.client_provider.sns_client
1416

@@ -33,7 +35,9 @@ def test_function_with_sns_bucket_trigger(self):
3335
self.assertEqual(sqs_subscription["TopicArn"], sns_topic_arn)
3436

3537
def test_function_with_sns_intrinsics(self):
36-
self.create_and_verify_stack("combination/function_with_sns_intrinsics")
38+
template_file_path = "combination/function_with_sns_intrinsics"
39+
self.skip_using_service_detector(template_file_path)
40+
self.create_and_verify_stack(template_file_path)
3741

3842
sns_client = self.client_provider.sns_client
3943

@@ -51,3 +55,4 @@ def test_function_with_sns_intrinsics(self):
5155
subscription_arn = subscription["SubscriptionArn"]
5256
subscription_attributes = sns_client.get_subscription_attributes(SubscriptionArn=subscription_arn)
5357
self.assertEqual(subscription_attributes["Attributes"]["FilterPolicy"], '{"price_usd":[{"numeric":["<",100]}]}')
58+
self.assertEqual(subscription_attributes["Attributes"]["FilterPolicyScope"], "MessageAttributes")

integration/combination/test_intrinsic_function_support.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,11 @@ def test_severless_api_properties_support(self):
5353

5454
self.assertTrue(
5555
get_api_policy_expectation in policy,
56-
"{} should be present in policy {}".format(get_api_policy_expectation, policy),
56+
f"{get_api_policy_expectation} should be present in policy {policy}",
5757
)
5858
self.assertTrue(
5959
post_api_policy_expectation in policy,
60-
"{} should be present in policy {}".format(post_api_policy_expectation, policy),
60+
f"{post_api_policy_expectation} should be present in policy {policy}",
6161
)
6262

6363
# Test for tags

integration/config/service_names.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
SNS = "SNS"
2323
SQS = "SQS"
2424
CUSTOM_DOMAIN = "CustomDomain"
25-
ARM = "ARM"
2625
EFS = "EFS"
2726
S3_EVENTS = "S3Events"
2827
SELF_MANAGED_KAFKA = "SelfManagedKafka"
@@ -36,3 +35,4 @@
3635
EPHEMERAL_STORAGE = "EphemeralStorage"
3736
API_KEY = "ApiKey"
3837
APP_SYNC = "AppSync"
38+
SNS_FILTER_POLICY_SCOPE = "SnsFilterPolicyScope"

integration/conftest.py

+6-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import logging
22
import time
3+
from pathlib import Path
34

45
import boto3
56
import botocore
@@ -18,11 +19,6 @@
1819
from integration.helpers.stack import Stack
1920
from integration.helpers.yaml_utils import load_yaml
2021

21-
try:
22-
from pathlib import Path
23-
except ImportError:
24-
from pathlib2 import Path
25-
2622
LOG = logging.getLogger(__name__)
2723

2824
COMPANION_STACK_NAME = "sam-integ-stack-companion"
@@ -175,16 +171,16 @@ def upload_resources(get_s3):
175171

176172
def get_s3_uri(file_name, uri_type, bucket, region):
177173
if uri_type == "s3":
178-
return "s3://{}/{}".format(bucket, file_name)
174+
return f"s3://{bucket}/{file_name}"
179175

180176
if region == "us-east-1":
181-
return "https://s3.amazonaws.com/{}/{}".format(bucket, file_name)
177+
return f"https://s3.amazonaws.com/{bucket}/{file_name}"
182178
if region == "us-iso-east-1":
183-
return "https://s3.us-iso-east-1.c2s.ic.gov/{}/{}".format(bucket, file_name)
179+
return f"https://s3.us-iso-east-1.c2s.ic.gov/{bucket}/{file_name}"
184180
if region == "us-isob-east-1":
185-
return "https://s3.us-isob-east-1.sc2s.sgov.gov/{}/{}".format(bucket, file_name)
181+
return f"https://s3.us-isob-east-1.sc2s.sgov.gov/{bucket}/{file_name}"
186182

187-
return "https://s3-{}.amazonaws.com/{}/{}".format(region, bucket, file_name)
183+
return f"https://s3-{region}.amazonaws.com/{bucket}/{file_name}"
188184

189185

190186
@pytest.fixture()

integration/helpers/base_test.py

+6-12
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
import logging
33
import os
44
import shutil
5+
from pathlib import Path
6+
from unittest.case import TestCase
57

8+
import boto3
69
import botocore
710
import pytest
811
import requests
@@ -20,6 +23,7 @@
2023

2124
from integration.config.logger_configurations import LoggingConfiguration
2225
from integration.helpers.client_provider import ClientProvider
26+
from integration.helpers.deployer.deployer import Deployer
2327
from integration.helpers.deployer.exceptions.exceptions import ThrottlingError
2428
from integration.helpers.deployer.utils.retry import retry_with_exponential_backoff_and_jitter
2529
from integration.helpers.exception import StatusCodeError
@@ -32,18 +36,8 @@
3236
verify_stack_resources,
3337
)
3438
from integration.helpers.s3_uploader import S3Uploader
35-
from integration.helpers.yaml_utils import dump_yaml, load_yaml
36-
37-
try:
38-
from pathlib import Path
39-
except ImportError:
40-
from pathlib2 import Path
41-
from unittest.case import TestCase
42-
43-
import boto3
44-
45-
from integration.helpers.deployer.deployer import Deployer
4639
from integration.helpers.template import transform_template
40+
from integration.helpers.yaml_utils import dump_yaml, load_yaml
4741

4842
LOG = logging.getLogger(__name__)
4943

@@ -422,7 +416,7 @@ def _fill_template(self, folder, file_name):
422416
data = f.read()
423417
for key, _ in self.code_key_to_file.items():
424418
# We must double the {} to escape them so they will survive a round of unescape
425-
data = data.replace("${{{}}}".format(key), self.get_code_key_s3_uri(key))
419+
data = data.replace(f"${{{key}}}", self.get_code_key_s3_uri(key))
426420
yaml_doc = yaml_parse(data)
427421

428422
dump_yaml(updated_template_path, yaml_doc)

integration/helpers/deployer/deployer.py

+5-5
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ def create_changeset(
140140
"ChangeSetType": changeset_type,
141141
"Parameters": parameter_values,
142142
"Capabilities": capabilities,
143-
"Description": "Created by SAM CLI at {0} UTC".format(datetime.utcnow().isoformat()),
143+
"Description": f"Created by SAM CLI at {datetime.utcnow().isoformat()} UTC",
144144
"Tags": tags,
145145
}
146146

@@ -172,7 +172,7 @@ def _create_change_set(self, stack_name, changeset_type, **kwargs):
172172
except botocore.exceptions.ClientError as ex:
173173
if "The bucket you are attempting to access must be addressed using the specified endpoint" in str(ex):
174174
raise deploy_exceptions.DeployBucketInDifferentRegionError(
175-
"Failed to create/update stack {}".format(stack_name)
175+
f"Failed to create/update stack {stack_name}"
176176
)
177177
raise deploy_exceptions.ChangeSetError(stack_name=stack_name, msg=str(ex))
178178

@@ -278,7 +278,7 @@ def wait_for_changeset(self, changeset_id, stack_name):
278278
raise deploy_exceptions.ChangeEmptyError(stack_name=stack_name)
279279

280280
raise deploy_exceptions.ChangeSetError(
281-
stack_name=stack_name, msg="ex: {0} Status: {1}. Reason: {2}".format(ex, status, reason)
281+
stack_name=stack_name, msg=f"ex: {ex} Status: {status}. Reason: {reason}"
282282
)
283283

284284
def execute_changeset(self, changeset_id, stack_name):
@@ -323,7 +323,7 @@ def wait_for_execute(self, stack_name, changeset_type):
323323
elif changeset_type == "UPDATE":
324324
waiter = self._client.get_waiter("stack_update_complete")
325325
else:
326-
raise RuntimeError("Invalid changeset type {0}".format(changeset_type))
326+
raise RuntimeError(f"Invalid changeset type {changeset_type}")
327327

328328
# Poll every 30 seconds. Polling too frequently risks hitting rate limits
329329
# on CloudFormation's DescribeStacks API
@@ -408,7 +408,7 @@ def get_stack_outputs(self, stack_name, echo=True):
408408
try:
409409
outputs = stacks_description["Stacks"][0]["Outputs"]
410410
if echo:
411-
sys.stdout.write("\nStack {stack_name} outputs:\n".format(stack_name=stack_name))
411+
sys.stdout.write(f"\nStack {stack_name} outputs:\n")
412412
sys.stdout.flush()
413413
self._display_stack_outputs(stack_outputs=outputs)
414414
return outputs

integration/helpers/deployer/utils/artifact_exporter.py

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
Logic for uploading to S3 per Cloudformation Specific Resource
33
This was ported over from the sam-cli repo
44
"""
5-
# pylint: disable=no-member
65

76
# Copyright 2012-2015 Amazon.com, Inc. or its affiliates. All Rights Reserved.
87
#

0 commit comments

Comments
 (0)