From 6e05d7dca425c952e8985cec1b9aa3cd40cb781b Mon Sep 17 00:00:00 2001 From: WatchTree-19 <119982314+WatchTree-19@users.noreply.github.com> Date: Sun, 17 May 2026 12:38:54 +0000 Subject: [PATCH] sdk: tighten `ReadableSpan.attributes` to non-Optional `Mapping` (#4569) The implementation always returns a `MappingProxyType`, never `None`, because `self._attributes or {}` falls back to an empty dict. Tightening the return annotation lets callers index `span.attributes["key"]` without type-checker complaints. Adds the towncrier fragment per CONTRIBUTING. Signed-off-by: WatchTree-19 <119982314+WatchTree-19@users.noreply.github.com> --- .changelog/5183.changed | 1 + opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 .changelog/5183.changed diff --git a/.changelog/5183.changed b/.changelog/5183.changed new file mode 100644 index 0000000000..e59614bf63 --- /dev/null +++ b/.changelog/5183.changed @@ -0,0 +1 @@ +`opentelemetry-sdk`: tighten `ReadableSpan.attributes` return type to non-Optional `Mapping` diff --git a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py index 9cdfebeb47..1901afabbd 100644 --- a/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py +++ b/opentelemetry-sdk/src/opentelemetry/sdk/trace/__init__.py @@ -492,7 +492,8 @@ def status(self) -> trace_api.Status: return self._status @property - def attributes(self) -> types.Attributes: + def attributes(self) -> Mapping[str, types.AttributeValue]: + # `or {}` keeps the return non-None; see #4569. return MappingProxyType(self._attributes or {}) @property