diff --git a/samtranslator/intrinsics/resolver.py b/samtranslator/intrinsics/resolver.py index 519f856fe..af79704a9 100644 --- a/samtranslator/intrinsics/resolver.py +++ b/samtranslator/intrinsics/resolver.py @@ -8,7 +8,7 @@ class IntrinsicsResolver(object): - def __init__(self, parameters, supported_intrinsics=DEFAULT_SUPPORTED_INTRINSICS): + def __init__(self, parameters, supported_intrinsics=None): """ Instantiate the resolver :param dict parameters: Map of parameter names to their values @@ -17,6 +17,8 @@ def __init__(self, parameters, supported_intrinsics=DEFAULT_SUPPORTED_INTRINSICS :raises TypeError: If parameters or the supported_intrinsics arguments are invalid """ + if supported_intrinsics is None: + supported_intrinsics = DEFAULT_SUPPORTED_INTRINSICS if parameters is None or not isinstance(parameters, dict): raise InvalidDocumentException( [InvalidTemplateException("'Mappings' or 'Parameters' is either null or not a valid dictionary.")] diff --git a/samtranslator/model/apigateway.py b/samtranslator/model/apigateway.py index 607c38529..0e768918f 100644 --- a/samtranslator/model/apigateway.py +++ b/samtranslator/model/apigateway.py @@ -231,8 +231,10 @@ def __init__( function_payload_type=None, function_invoke_role=None, is_aws_iam_authorizer=False, - authorization_scopes=[], + authorization_scopes=None, ): + if authorization_scopes is None: + authorization_scopes = [] if function_payload_type not in ApiGatewayAuthorizer._VALID_FUNCTION_PAYLOAD_TYPES: raise InvalidResourceException( api_logical_id, diff --git a/samtranslator/model/intrinsics.py b/samtranslator/model/intrinsics.py index c81e40d00..e95a5d6d0 100644 --- a/samtranslator/model/intrinsics.py +++ b/samtranslator/model/intrinsics.py @@ -24,7 +24,9 @@ def fnAnd(argument_list): return {"Fn::And": argument_list} -def make_conditional(condition, true_data, false_data={"Ref": "AWS::NoValue"}): +def make_conditional(condition, true_data, false_data=None): + if false_data is None: + false_data = {"Ref": "AWS::NoValue"} return {"Fn::If": [condition, true_data, false_data]} diff --git a/samtranslator/model/stepfunctions/generators.py b/samtranslator/model/stepfunctions/generators.py index 8e1797c7d..f8431c189 100644 --- a/samtranslator/model/stepfunctions/generators.py +++ b/samtranslator/model/stepfunctions/generators.py @@ -286,7 +286,7 @@ def _replace_dynamic_values_with_substitutions(self, input): location[path[-1]] = sub_key return substitution_map - def _get_paths_to_intrinsics(self, input, path=[]): + def _get_paths_to_intrinsics(self, input, path=None): """ Returns all paths to dynamic values within a dictionary @@ -294,6 +294,8 @@ def _get_paths_to_intrinsics(self, input, path=[]): :param path: Optional list to keep track of the path to the input dictionary :returns list: List of keys that defines the path to a dynamic value within the input dictionary """ + if path is None: + path = [] dynamic_value_paths = [] if isinstance(input, dict): iterator = input.items() diff --git a/samtranslator/open_api/open_api.py b/samtranslator/open_api/open_api.py index fc0f77a26..af6b47e49 100644 --- a/samtranslator/open_api/open_api.py +++ b/samtranslator/open_api/open_api.py @@ -391,7 +391,7 @@ def add_auth_to_method(self, path, method_name, auth, api): if method_authorizer: self._set_method_authorizer(path, method_name, method_authorizer, authorizers, authorization_scopes) - def _set_method_authorizer(self, path, method_name, authorizer_name, authorizers, authorization_scopes=[]): + def _set_method_authorizer(self, path, method_name, authorizer_name, authorizers, authorization_scopes=None): """ Adds the authorizer_name to the security block for each method on this path. This is used to configure the authorizer for individual functions. @@ -402,6 +402,8 @@ def _set_method_authorizer(self, path, method_name, authorizer_name, authorizers authorizers param. :param list authorization_scopes: list of strings that are the auth scopes for this method """ + if authorization_scopes is None: + authorization_scopes = [] normalized_method_name = self._normalize_method_name(method_name) # It is possible that the method could have two definitions in a Fn::If block. for method_definition in self.get_method_contents(self.get_path(path)[normalized_method_name]): diff --git a/samtranslator/plugins/application/serverless_app_plugin.py b/samtranslator/plugins/application/serverless_app_plugin.py index 02333e0f4..05741c5df 100644 --- a/samtranslator/plugins/application/serverless_app_plugin.py +++ b/samtranslator/plugins/application/serverless_app_plugin.py @@ -42,7 +42,7 @@ class ServerlessAppPlugin(BasePlugin): LOCATION_KEY = "Location" TEMPLATE_URL_KEY = "TemplateUrl" - def __init__(self, sar_client=None, wait_for_template_active_status=False, validate_only=False, parameters={}): + def __init__(self, sar_client=None, wait_for_template_active_status=False, validate_only=False, parameters=None): """ Initialize the plugin. @@ -52,6 +52,8 @@ def __init__(self, sar_client=None, wait_for_template_active_status=False, valid :param bool validate_only: Flag to only validate application access (uses get_application API instead) """ super(ServerlessAppPlugin, self).__init__(ServerlessAppPlugin.__name__) + if parameters is None: + parameters = {} self._applications = {} self._in_progress_templates = [] self._sar_client = sar_client diff --git a/samtranslator/swagger/swagger.py b/samtranslator/swagger/swagger.py index 64e6699b8..4345373c0 100644 --- a/samtranslator/swagger/swagger.py +++ b/samtranslator/swagger/swagger.py @@ -698,7 +698,7 @@ def add_auth_to_method(self, path, method_name, auth, api): if method_apikey_required is not None: self._set_method_apikey_handling(path, method_name, method_apikey_required) - def _set_method_authorizer(self, path, method_name, authorizer_name, authorizers={}, method_scopes=None): + def _set_method_authorizer(self, path, method_name, authorizer_name, authorizers=None, method_scopes=None): """ Adds the authorizer_name to the security block for each method on this path. This is used to configure the authorizer for individual functions. @@ -708,6 +708,8 @@ def _set_method_authorizer(self, path, method_name, authorizer_name, authorizers :param string authorizer_name: Name of the authorizer to use. Must be a key in the authorizers param. """ + if authorizers is None: + authorizers = {} normalized_method_name = self._normalize_method_name(method_name) # It is possible that the method could have two definitions in a Fn::If block. for method_definition in self.get_method_contents(self.get_path(path)[normalized_method_name]): diff --git a/samtranslator/translator/arn_generator.py b/samtranslator/translator/arn_generator.py index 9394a6c0a..897661e8d 100644 --- a/samtranslator/translator/arn_generator.py +++ b/samtranslator/translator/arn_generator.py @@ -6,7 +6,7 @@ class NoRegionFound(Exception): class ArnGenerator(object): - class_boto_session = None + BOTO_SESSION_REGION_NAME = None @classmethod def generate_arn(cls, partition, service, resource, include_account_id=True): @@ -50,10 +50,10 @@ def get_partition_name(cls, region=None): # Use Boto3 to get the region where code is running. This uses Boto's regular region resolution # mechanism, starting from AWS_DEFAULT_REGION environment variable. - if ArnGenerator.class_boto_session is None: + if ArnGenerator.BOTO_SESSION_REGION_NAME is None: region = boto3.session.Session().region_name else: - region = ArnGenerator.class_boto_session.region_name + region = ArnGenerator.BOTO_SESSION_REGION_NAME # If region is still None, then we could not find the region. This will only happen # in the local context. When this is deployed, we will be able to find the region like diff --git a/samtranslator/translator/translator.py b/samtranslator/translator/translator.py index b7449e02e..c7d7c415b 100644 --- a/samtranslator/translator/translator.py +++ b/samtranslator/translator/translator.py @@ -45,7 +45,8 @@ def __init__(self, managed_policy_map, sam_parser, plugins=None, boto_session=No self.feature_toggle = None self.boto_session = boto_session - ArnGenerator.class_boto_session = self.boto_session + if self.boto_session: + ArnGenerator.BOTO_SESSION_REGION_NAME = self.boto_session.region_name def _get_function_names(self, resource_dict, intrinsics_resolver): """ @@ -226,7 +227,7 @@ def _get_resources_to_iterate(self, sam_template, macro_resolver): return functions + statemachines + apis + others -def prepare_plugins(plugins, parameters={}): +def prepare_plugins(plugins, parameters=None): """ Creates & returns a plugins object with the given list of plugins installed. In addition to the given plugins, we will also install a few "required" plugins that are necessary to provide complete support for SAM template spec. @@ -236,6 +237,8 @@ def prepare_plugins(plugins, parameters={}): :return samtranslator.plugins.SamPlugins: Instance of `SamPlugins` """ + if parameters is None: + parameters = {} required_plugins = [ DefaultDefinitionBodyPlugin(), make_implicit_rest_api_plugin(), diff --git a/tests/intrinsics/test_resolver.py b/tests/intrinsics/test_resolver.py index 2f62b510f..946307b87 100644 --- a/tests/intrinsics/test_resolver.py +++ b/tests/intrinsics/test_resolver.py @@ -192,11 +192,6 @@ class SomeAction(Action): with self.assertRaises(TypeError): IntrinsicsResolver({}, supported_intrinsics) - def test_configure_supported_intrinsics_must_error_for_none_input(self): - - with self.assertRaises(TypeError): - IntrinsicsResolver({}, None) - def test_configure_supported_intrinsics_must_error_for_non_dict_input(self): with self.assertRaises(TypeError): diff --git a/tests/translator/test_arn_generator.py b/tests/translator/test_arn_generator.py index 461840cdf..200f90414 100644 --- a/tests/translator/test_arn_generator.py +++ b/tests/translator/test_arn_generator.py @@ -1,13 +1,13 @@ from unittest import TestCase from parameterized import parameterized -from mock import Mock, patch +from mock import patch from samtranslator.translator.arn_generator import ArnGenerator, NoRegionFound class TestArnGenerator(TestCase): def setUp(self): - ArnGenerator.class_boto_session = None + ArnGenerator.BOTO_SESSION_REGION_NAME = None @parameterized.expand( [("us-east-1", "aws"), ("cn-east-1", "aws-cn"), ("us-gov-west-1", "aws-us-gov"), ("US-EAST-1", "aws")] @@ -23,13 +23,10 @@ def test_get_partition_name_raise_NoRegionFound(self): ArnGenerator.get_partition_name(None) def test_get_partition_name_from_boto_session(self): - boto_session_mock = Mock() - boto_session_mock.region_name = "us-east-1" - - ArnGenerator.class_boto_session = boto_session_mock + ArnGenerator.BOTO_SESSION_REGION_NAME = "us-east-1" actual = ArnGenerator.get_partition_name() self.assertEqual(actual, "aws") - ArnGenerator.class_boto_session = None + ArnGenerator.BOTO_SESSION_REGION_NAME = None