Skip to content
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

- `opentelemetry-api`: Replace a broad exception in attribute cleaning tests to satisfy pylint in the `lint-opentelemetry-api` CI job
- `opentelemetry-sdk`: Add `create_resource` and `create_propagator`/`configure_propagator` to declarative file configuration, enabling Resource and propagator instantiation from config files without reading env vars
([#4979](https://github.com/open-telemetry/opentelemetry-python/pull/4979))
- `opentelemetry-sdk`: Map Python `CRITICAL` log level to OTel `FATAL` severity text per the specification
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,13 @@
)


# TODO: Remove this workaround and revert to the simpler implementation
# once Python 3.9 support is dropped (planned around May 2026).
# This exists only to avoid issues caused by deprecated behavior in 3.9.
def _type_name(t):
return getattr(t, "__name__", getattr(t, "_name", repr(t)))


_logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -191,7 +198,7 @@ def _clean_extended_attribute_value( # pylint: disable=too-many-branches
except Exception:
raise TypeError(
f"Invalid type {type(value).__name__} for attribute value. "
f"Expected one of {[valid_type.__name__ for valid_type in _VALID_ANY_VALUE_TYPES]} or a "
f"Expected one of {[_type_name(valid_type) for valid_type in _VALID_ANY_VALUE_TYPES]} or a "
"sequence of those types",
)

Expand Down
10 changes: 10 additions & 0 deletions opentelemetry-api/tests/attributes/test_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@

import copy
import unittest
import unittest.mock
from typing import MutableSequence

from opentelemetry.attributes import (
BoundedAttributes,
_clean_attribute,
_clean_extended_attribute,
_clean_extended_attribute_value,
)


Expand Down Expand Up @@ -322,6 +324,14 @@ def __str__(self):
"<DummyWSGIRequest method=GET path=/example/>", cleaned_value
)

def test_invalid_anyvalue_type_raises_typeerror(self):
class BadStr:
def __str__(self):
raise RuntimeError("boom")

with self.assertRaises(TypeError):
_clean_extended_attribute_value(BadStr(), None)

def test_deepcopy(self):
bdict = BoundedAttributes(4, self.base, immutable=False)
bdict.dropped = 10
Expand Down
Loading