diff --git a/opentelemetry-api/src/opentelemetry/attributes/__init__.py b/opentelemetry-api/src/opentelemetry/attributes/__init__.py index 5116c2fdd8..d5ffbf824b 100644 --- a/opentelemetry-api/src/opentelemetry/attributes/__init__.py +++ b/opentelemetry-api/src/opentelemetry/attributes/__init__.py @@ -36,6 +36,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__) @@ -190,7 +197,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", ) diff --git a/opentelemetry-api/tests/attributes/test_attributes.py b/opentelemetry-api/tests/attributes/test_attributes.py index 8cb6f35fbc..31bf216be5 100644 --- a/opentelemetry-api/tests/attributes/test_attributes.py +++ b/opentelemetry-api/tests/attributes/test_attributes.py @@ -15,12 +15,14 @@ # type: ignore import unittest +import unittest.mock from typing import MutableSequence from opentelemetry.attributes import ( BoundedAttributes, _clean_attribute, _clean_extended_attribute, + _clean_extended_attribute_value, ) @@ -320,3 +322,11 @@ def __str__(self): self.assertEqual( "", cleaned_value ) + + def test_invalid_anyvalue_type_raises_typeerror(self): + class BadStr: + def __str__(self): + raise Exception("boom") + + with self.assertRaises(TypeError): + _clean_extended_attribute_value(BadStr(), None)