Skip to content

Commit a65e1fb

Browse files
authored
Merge branch 'develop' into ci-bump-12026246999
2 parents 51deb1d + 73e5816 commit a65e1fb

File tree

8 files changed

+111
-51
lines changed

8 files changed

+111
-51
lines changed

.github/workflows/on_closed_issues.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
permissions:
2222
issues: write # comment on issues
2323
steps:
24-
- uses: aws-actions/closed-issue-message@80edfc24bdf1283400eb04d20a8a605ae8bf7d48
24+
- uses: aws-powertools/actions/.github/actions/close-issue-message@428c1934f4b22c0984ff4a39b66c2f70765bbed6
2525
with:
2626
repo-token: "${{ secrets.GITHUB_TOKEN }}"
2727
message: |

CHANGELOG.md

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,41 +27,44 @@
2727
## Maintenance
2828

2929
* **ci:** new pre-release 3.3.1a4 ([#5612](https://github.com/aws-powertools/powertools-lambda-python/issues/5612))
30+
* **ci:** revert closed issue action update ([#5637](https://github.com/aws-powertools/powertools-lambda-python/issues/5637))
31+
* **ci:** new pre-release 3.3.1a5 ([#5639](https://github.com/aws-powertools/powertools-lambda-python/issues/5639))
32+
* **ci:** replace closed-issue-message action with powertools action ([#5641](https://github.com/aws-powertools/powertools-lambda-python/issues/5641))
3033
* **ci:** new pre-release 3.3.1a0 ([#5565](https://github.com/aws-powertools/powertools-lambda-python/issues/5565))
3134
* **ci:** new pre-release 3.3.1a1 ([#5577](https://github.com/aws-powertools/powertools-lambda-python/issues/5577))
3235
* **ci:** remove poetry cache in quality check pipeline ([#5626](https://github.com/aws-powertools/powertools-lambda-python/issues/5626))
3336
* **ci:** new pre-release 3.3.1a2 ([#5585](https://github.com/aws-powertools/powertools-lambda-python/issues/5585))
3437
* **ci:** new pre-release 3.3.1a3 ([#5598](https://github.com/aws-powertools/powertools-lambda-python/issues/5598))
3538
* **deps:** bump codecov/codecov-action from 5.0.2 to 5.0.3 ([#5592](https://github.com/aws-powertools/powertools-lambda-python/issues/5592))
36-
* **deps:** bump datadog-lambda from 6.102.0 to 6.104.0 ([#5631](https://github.com/aws-powertools/powertools-lambda-python/issues/5631))
39+
* **deps:** bump pydantic from 2.10.0 to 2.10.1 ([#5632](https://github.com/aws-powertools/powertools-lambda-python/issues/5632))
3740
* **deps:** bump actions/dependency-review-action from 4.4.0 to 4.5.0 ([#5616](https://github.com/aws-powertools/powertools-lambda-python/issues/5616))
3841
* **deps:** bump codecov/codecov-action from 5.0.3 to 5.0.7 ([#5617](https://github.com/aws-powertools/powertools-lambda-python/issues/5617))
3942
* **deps:** bump squidfunk/mkdocs-material from `ce587cb` to `ef0b45e` in /docs ([#5603](https://github.com/aws-powertools/powertools-lambda-python/issues/5603))
4043
* **deps:** bump aws-actions/closed-issue-message from 80edfc24bdf1283400eb04d20a8a605ae8bf7d48 to 37548691e7cc75ba58f85c9f873f9eee43590449 ([#5606](https://github.com/aws-powertools/powertools-lambda-python/issues/5606))
41-
* **deps:** bump aws-encryption-sdk from 3.3.0 to 4.0.0 ([#5564](https://github.com/aws-powertools/powertools-lambda-python/issues/5564))
44+
* **deps:** bump codecov/codecov-action from 4.6.0 to 5.0.2 ([#5567](https://github.com/aws-powertools/powertools-lambda-python/issues/5567))
4245
* **deps:** bump pydantic from 2.9.2 to 2.10.0 ([#5611](https://github.com/aws-powertools/powertools-lambda-python/issues/5611))
46+
* **deps:** bump aws-encryption-sdk from 3.3.0 to 4.0.0 ([#5564](https://github.com/aws-powertools/powertools-lambda-python/issues/5564))
4347
* **deps:** bump datadog-lambda from 6.101.0 to 6.102.0 ([#5570](https://github.com/aws-powertools/powertools-lambda-python/issues/5570))
44-
* **deps:** bump pydantic from 2.10.0 to 2.10.1 ([#5632](https://github.com/aws-powertools/powertools-lambda-python/issues/5632))
45-
* **deps:** bump codecov/codecov-action from 4.6.0 to 5.0.2 ([#5567](https://github.com/aws-powertools/powertools-lambda-python/issues/5567))
46-
* **deps-dev:** bump boto3-stubs from 1.35.64 to 1.35.67 ([#5621](https://github.com/aws-powertools/powertools-lambda-python/issues/5621))
48+
* **deps:** bump datadog-lambda from 6.102.0 to 6.104.0 ([#5631](https://github.com/aws-powertools/powertools-lambda-python/issues/5631))
49+
* **deps-dev:** bump aws-cdk from 2.167.2 to 2.169.0 ([#5618](https://github.com/aws-powertools/powertools-lambda-python/issues/5618))
4750
* **deps-dev:** bump aws-cdk-lib from 2.167.1 to 2.167.2 ([#5596](https://github.com/aws-powertools/powertools-lambda-python/issues/5596))
48-
* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.281 to 0.1.282 ([#5594](https://github.com/aws-powertools/powertools-lambda-python/issues/5594))
51+
* **deps-dev:** bump boto3-stubs from 1.35.64 to 1.35.67 ([#5621](https://github.com/aws-powertools/powertools-lambda-python/issues/5621))
4952
* **deps-dev:** bump boto3-stubs from 1.35.63 to 1.35.64 ([#5582](https://github.com/aws-powertools/powertools-lambda-python/issues/5582))
50-
* **deps-dev:** bump aws-cdk from 2.167.1 to 2.167.2 ([#5593](https://github.com/aws-powertools/powertools-lambda-python/issues/5593))
53+
* **deps-dev:** bump mkdocs-material from 9.5.44 to 9.5.45 ([#5610](https://github.com/aws-powertools/powertools-lambda-python/issues/5610))
5154
* **deps-dev:** bump aws-cdk-aws-lambda-python-alpha from 2.167.0a0 to 2.167.1a0 ([#5583](https://github.com/aws-powertools/powertools-lambda-python/issues/5583))
55+
* **deps-dev:** bump aws-cdk from 2.167.1 to 2.167.2 ([#5593](https://github.com/aws-powertools/powertools-lambda-python/issues/5593))
5256
* **deps-dev:** bump cfn-lint from 1.19.0 to 1.20.0 ([#5595](https://github.com/aws-powertools/powertools-lambda-python/issues/5595))
57+
* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.281 to 0.1.282 ([#5594](https://github.com/aws-powertools/powertools-lambda-python/issues/5594))
5358
* **deps-dev:** bump aws-cdk-lib from 2.167.2 to 2.170.0 ([#5622](https://github.com/aws-powertools/powertools-lambda-python/issues/5622))
54-
* **deps-dev:** bump aws-cdk-aws-lambda-python-alpha from 2.167.1a0 to 2.167.2a0 ([#5619](https://github.com/aws-powertools/powertools-lambda-python/issues/5619))
55-
* **deps-dev:** bump ruff from 0.7.3 to 0.7.4 ([#5569](https://github.com/aws-powertools/powertools-lambda-python/issues/5569))
5659
* **deps-dev:** bump boto3-stubs from 1.35.60 to 1.35.63 ([#5581](https://github.com/aws-powertools/powertools-lambda-python/issues/5581))
57-
* **deps-dev:** bump mkdocs-material from 9.5.44 to 9.5.45 ([#5610](https://github.com/aws-powertools/powertools-lambda-python/issues/5610))
58-
* **deps-dev:** bump aws-cdk from 2.167.0 to 2.167.1 ([#5572](https://github.com/aws-powertools/powertools-lambda-python/issues/5572))
5960
* **deps-dev:** bump sentry-sdk from 2.18.0 to 2.19.0 ([#5633](https://github.com/aws-powertools/powertools-lambda-python/issues/5633))
60-
* **deps-dev:** bump aws-cdk-aws-lambda-python-alpha from 2.167.2a0 to 2.170.0a0 ([#5629](https://github.com/aws-powertools/powertools-lambda-python/issues/5629))
61-
* **deps-dev:** bump aws-cdk-lib from 2.167.0 to 2.167.1 ([#5568](https://github.com/aws-powertools/powertools-lambda-python/issues/5568))
61+
* **deps-dev:** bump aws-cdk from 2.167.0 to 2.167.1 ([#5572](https://github.com/aws-powertools/powertools-lambda-python/issues/5572))
6262
* **deps-dev:** bump cdklabs-generative-ai-cdk-constructs from 0.1.282 to 0.1.284 ([#5607](https://github.com/aws-powertools/powertools-lambda-python/issues/5607))
63+
* **deps-dev:** bump ruff from 0.7.3 to 0.7.4 ([#5569](https://github.com/aws-powertools/powertools-lambda-python/issues/5569))
64+
* **deps-dev:** bump aws-cdk-lib from 2.167.0 to 2.167.1 ([#5568](https://github.com/aws-powertools/powertools-lambda-python/issues/5568))
6365
* **deps-dev:** bump aws-cdk from 2.169.0 to 2.170.0 ([#5628](https://github.com/aws-powertools/powertools-lambda-python/issues/5628))
64-
* **deps-dev:** bump aws-cdk from 2.167.2 to 2.169.0 ([#5618](https://github.com/aws-powertools/powertools-lambda-python/issues/5618))
66+
* **deps-dev:** bump aws-cdk-aws-lambda-python-alpha from 2.167.2a0 to 2.170.0a0 ([#5629](https://github.com/aws-powertools/powertools-lambda-python/issues/5629))
67+
* **deps-dev:** bump aws-cdk-aws-lambda-python-alpha from 2.167.1a0 to 2.167.2a0 ([#5619](https://github.com/aws-powertools/powertools-lambda-python/issues/5619))
6568
* **layers:** balance Python 3.13 layers in GovCloud partition ([#5579](https://github.com/aws-powertools/powertools-lambda-python/issues/5579))
6669

6770

aws_lambda_powertools/logging/formatter.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ def formatTime(self, record: logging.LogRecord, datefmt: str | None = None) -> s
222222
# NOTE: Python `time.strftime` doesn't provide msec directives
223223
# so we create a custom one (%F) and replace logging record_ts
224224
# Reason 2 is that std logging doesn't support msec after TZ
225-
msecs = "%03d" % record.msecs
225+
msecs = "%03d" % record.msecs # noqa UP031
226226

227227
# Datetime format codes is a superset of time format codes
228228
# therefore we only honour them if explicitly asked
@@ -425,7 +425,9 @@ def _strip_none_records(records: dict[str, Any]) -> dict[str, Any]:
425425
RESERVED_FORMATTER_CUSTOM_KEYS: list[str] = inspect.getfullargspec(LambdaPowertoolsFormatter).args[1:]
426426

427427
# ContextVar for thread local keys
428-
THREAD_LOCAL_KEYS: ContextVar[dict[str, Any]] = ContextVar("THREAD_LOCAL_KEYS", default={})
428+
default_contextvar: dict[str, Any] = {}
429+
430+
THREAD_LOCAL_KEYS: ContextVar[dict[str, Any]] = ContextVar("THREAD_LOCAL_KEYS", default=default_contextvar)
429431

430432

431433
def _get_context() -> ContextVar[dict[str, Any]]:

aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
from aws_lambda_powertools.metrics.provider.cloudwatch_emf.metric_properties import MetricResolution, MetricUnit
2323
from aws_lambda_powertools.shared import constants
2424
from aws_lambda_powertools.shared.functions import resolve_env_var_choice
25+
from aws_lambda_powertools.warnings import PowertoolsUserWarning
26+
2527

2628
if TYPE_CHECKING:
2729
from aws_lambda_powertools.metrics.provider.cloudwatch_emf.types import CloudWatchEMFOutput
@@ -278,14 +280,22 @@ def add_dimension(self, name: str, value: str) -> None:
278280
if not name.strip() or not value.strip():
279281
warnings.warn(
280282
f"The dimension {name} doesn't meet the requirements and won't be added. "
281-
"Ensure the dimension name and value are non empty strings",
283+
"Ensure the dimension name and value are non-empty strings",
284+
category=PowertoolsUserWarning,
282285
stacklevel=2,
283286
)
284-
else:
285-
# Cast value to str according to EMF spec
286-
# Majority of values are expected to be string already, so
287-
# checking before casting improves performance in most cases
288-
self.dimension_set[name] = value
287+
return
288+
289+
if name in self.dimension_set or name in self.default_dimensions:
290+
warnings.warn(
291+
f"Dimension '{name}' has already been added. The previous value will be overwritten.",
292+
category=PowertoolsUserWarning,
293+
stacklevel=2,
294+
)
295+
296+
self.dimension_set[name] = value
297+
298+
289299

290300
def add_metadata(self, key: str, value: Any) -> None:
291301
"""Adds high cardinal metadata for metrics object
@@ -294,7 +304,7 @@ def add_metadata(self, key: str, value: Any) -> None:
294304
Instead, this will be searchable through logs.
295305
296306
If you're looking to add metadata to filter metrics, then
297-
use add_dimensions method.
307+
use add_dimension method.
298308
299309
Example
300310
-------

poetry.lock

Lines changed: 27 additions & 26 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ types-python-dateutil = "^2.8.19.6"
115115
aws-cdk-aws-appsync-alpha = "^2.59.0a0"
116116
httpx = ">=0.23.3,<0.28.0"
117117
sentry-sdk = ">=1.22.2,<3.0.0"
118-
ruff = ">=0.5.1,<0.7.5"
118+
ruff = ">=0.5.1,<0.8.1"
119119
retry2 = "^0.9.5"
120120
pytest-socket = ">=0.6,<0.8"
121121
types-redis = "^4.6.0.7"

tests/functional/logger/required_dependencies/test_logger_powertools_formatter.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import random
77
import re
88
import string
9+
import sys
910
import time
1011
from collections import namedtuple
1112
from threading import Thread
@@ -453,6 +454,7 @@ def send_thread_message_with_key(message, keys):
453454
assert logs[3].get("exampleThread2Key") is None
454455

455456

457+
@pytest.mark.skipif(sys.version_info >= (3, 13), reason="Test temporarily disabled for Python 3.13+")
456458
def test_thread_safe_remove_key(service_name, stdout):
457459
logger = Logger(
458460
service=service_name,
@@ -469,6 +471,7 @@ def send_message_with_key_and_without(message, keys):
469471
Thread(target=send_message_with_key_and_without, args=("msg", thread1_keys)).start()
470472

471473
logs = capture_logging_output(stdout)
474+
print(logs)
472475

473476
assert logs[0].get("exampleThread1Key") == "thread1"
474477
assert logs[1].get("exampleThread1Key") is None

tests/unit/metrics/test_functions.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import pytest
2+
import warnings
23

34
from aws_lambda_powertools.metrics.functions import (
45
extract_cloudwatch_metric_resolution_value,
@@ -9,6 +10,18 @@
910
MetricUnitError,
1011
)
1112
from aws_lambda_powertools.metrics.provider.cloudwatch_emf.metric_properties import MetricResolution, MetricUnit
13+
from aws_lambda_powertools.metrics import Metrics
14+
from aws_lambda_powertools.warnings import PowertoolsUserWarning
15+
16+
@pytest.fixture
17+
def warning_catcher(monkeypatch):
18+
caught_warnings = []
19+
20+
def custom_warn(message, category=None, stacklevel=1, source=None):
21+
caught_warnings.append(PowertoolsUserWarning(message))
22+
23+
monkeypatch.setattr(warnings, 'warn', custom_warn)
24+
return caught_warnings
1225

1326

1427
def test_extract_invalid_cloudwatch_metric_resolution_value():
@@ -61,3 +74,31 @@ def test_extract_valid_cloudwatch_metric_unit_value():
6174

6275
# THEN value must be extracted
6376
assert extracted_unit_value == unit
77+
78+
79+
def test_add_dimension_overwrite_warning(warning_catcher):
80+
"""
81+
Adds a dimension and then tries to add another with the same name
82+
but a different value. Verifies if the dimension is updated with
83+
the new value and warning is issued when an existing dimension
84+
is overwritten.
85+
"""
86+
metrics = Metrics(namespace="TestNamespace")
87+
88+
# GIVEN default dimension
89+
dimension_name = "test-dimension"
90+
value1 = "test-value-1"
91+
value2 = "test-value-2"
92+
93+
# WHEN adding the same dimension twice with different values
94+
metrics.add_dimension(dimension_name, value1)
95+
metrics.add_dimension(dimension_name, value2)
96+
97+
# THEN the dimension should be updated with the new value
98+
assert metrics._dimensions[dimension_name] == value2
99+
100+
# AND a warning should be issued with the exact message
101+
expected_warning = f"Dimension '{dimension_name}' has already been added. The previous value will be overwritten."
102+
assert any(str(w) == expected_warning for w in warning_catcher)
103+
104+

0 commit comments

Comments
 (0)