From 53084744e0a0e4f43594efc1c6820d9d54a3928c Mon Sep 17 00:00:00 2001 From: SumiRann1 Date: Sun, 18 Oct 2026 17:39:03 +0530 Subject: [PATCH 1/2] fix(parameters): avoid mutating caller's dict in get_parameters_by_name --- .../utilities/parameters/ssm.py | 4 +-- .../_boto3/test_utilities_parameters.py | 34 +++++++++++++++++++ 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/aws_lambda_powertools/utilities/parameters/ssm.py b/aws_lambda_powertools/utilities/parameters/ssm.py index 6ce4f853459..79758ada21b 100644 --- a/aws_lambda_powertools/utilities/parameters/ssm.py +++ b/aws_lambda_powertools/utilities/parameters/ssm.py @@ -713,7 +713,7 @@ def _split_batch_and_decrypt_parameters( for parameter, options in parameters.items(): # NOTE: TypeDict later - _overrides = options or {} + _overrides = {**(options or {})} _overrides["transform"] = _overrides.get("transform") or transform # These values can be falsy (False, 0) @@ -723,7 +723,7 @@ def _split_batch_and_decrypt_parameters( if "max_age" not in _overrides: _overrides["max_age"] = max_age - # NOTE: Split parameters who have decrypt OR have it global + # NOTE: Split qparameters who have decrypt OR have it global if _overrides["decrypt"]: decrypt_parameters[parameter] = _overrides else: diff --git a/tests/functional/parameters/_boto3/test_utilities_parameters.py b/tests/functional/parameters/_boto3/test_utilities_parameters.py index dc7643795c1..bf11dbcf1c4 100644 --- a/tests/functional/parameters/_boto3/test_utilities_parameters.py +++ b/tests/functional/parameters/_boto3/test_utilities_parameters.py @@ -1279,6 +1279,40 @@ def test_ssm_provider_get_parameters_by_name_all_decrypt_should_use_get_paramete stubber.deactivate() +def test_ssm_provider_get_parameters_by_name_does_not_mutate_input_and_honors_new_globals( + mock_name, + mock_value, + config, +): + # GIVEN a reusable parameters dict with a non-empty per-parameter override + param = f"/a/{mock_name}" + fail = "/does_not_exist" # stub model doesn't support all-success yet + all_params = {param: {"max_age": 0}, fail: {}} + names = list(all_params.keys()) + stub_response = build_get_parameters_stub(params={param: mock_value}, invalid_parameters=[fail]) + + provider = parameters.SSMProvider(boto_config=config) + stubber = stub.Stubber(provider.client) + # first call: global decrypt defaults to False -> no WithDecryption + stubber.add_response("get_parameters", stub_response, {"Names": names}) + # second call: new global decrypt=True must be honored + stubber.add_response("get_parameters", stub_response, {"Names": names, "WithDecryption": True}) + stubber.activate() + + # WHEN get_parameters_by_name is called twice with different global options + try: + provider.get_parameters_by_name(parameters=all_params, raise_on_error=False) + + # THEN the caller's dict must not be modified + assert all_params == {param: {"max_age": 0}, fail: {}} + + # AND a later global decrypt=True must not be overridden by stale values + provider.get_parameters_by_name(parameters=all_params, decrypt=True, raise_on_error=False) + stubber.assert_no_pending_responses() + finally: + stubber.deactivate() + + def test_dynamodb_provider_clear_cache(mock_name, mock_value, config): # GIVEN a provider is initialized with a cached value provider = parameters.DynamoDBProvider(table_name="test", boto_config=config) From 2d78d3df95237329ce541ac2bf55bc7715cbc094 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Mon, 19 Oct 2026 09:10:09 +0000 Subject: [PATCH 2/2] chore(parameters): fix typo in comment --- aws_lambda_powertools/utilities/parameters/ssm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws_lambda_powertools/utilities/parameters/ssm.py b/aws_lambda_powertools/utilities/parameters/ssm.py index 79758ada21b..a404b29f764 100644 --- a/aws_lambda_powertools/utilities/parameters/ssm.py +++ b/aws_lambda_powertools/utilities/parameters/ssm.py @@ -723,7 +723,7 @@ def _split_batch_and_decrypt_parameters( if "max_age" not in _overrides: _overrides["max_age"] = max_age - # NOTE: Split qparameters who have decrypt OR have it global + # NOTE: Split parameters who have decrypt OR have it global if _overrides["decrypt"]: decrypt_parameters[parameter] = _overrides else: