From 5491829cc470e0d846d39f9b44d8db7810f969a8 Mon Sep 17 00:00:00 2001 From: Jgprog117 Date: Sat, 31 Jan 2026 12:51:25 +0100 Subject: [PATCH] Fix AttributeError when generating error message on Python 3.9 On Python 3.9, when an invalid attribute value is passed that cannot be converted to a string, the code raises AttributeError instead of the intended TypeError. This is because the error message generation tries to access __name__ on all types in _VALID_ANY_VALUE_TYPES, but typing.Mapping (and other generic types) don't have a __name__ attribute in Python 3.9. This fix uses getattr with fallback to _name attribute to safely handle types that don't have __name__. Fixes #4821 --- .../src/opentelemetry/attributes/__init__.py | 2 +- .../tests/attributes/test_attributes.py | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/opentelemetry-api/src/opentelemetry/attributes/__init__.py b/opentelemetry-api/src/opentelemetry/attributes/__init__.py index 5116c2fdd8..8fc80125a8 100644 --- a/opentelemetry-api/src/opentelemetry/attributes/__init__.py +++ b/opentelemetry-api/src/opentelemetry/attributes/__init__.py @@ -190,7 +190,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 {[getattr(valid_type, '__name__', getattr(valid_type, '_name', None)) 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..6781b05352 100644 --- a/opentelemetry-api/tests/attributes/test_attributes.py +++ b/opentelemetry-api/tests/attributes/test_attributes.py @@ -320,3 +320,25 @@ def __str__(self): self.assertEqual( "", cleaned_value ) + + def test_invalid_type_error_message(self): + """Test that invalid types that cannot be converted to string raise TypeError with proper message. + + This test specifically addresses issue #4821 where on Python 3.9, the error message + generation would fail with AttributeError when accessing __name__ on generic types like Mapping. + """ + + class UnstringifiableObject: + """An object that cannot be converted to string.""" + + def __str__(self): + raise ValueError("Cannot convert to string") + + invalid_value = UnstringifiableObject() + + # Should return None and log warning, not raise AttributeError + cleaned_value = _clean_extended_attribute( + "test_key", invalid_value, None + ) + + self.assertIsNone(cleaned_value)