Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions aws_xray_sdk/core/utils/conversion.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from collections.abc import Iterable
import logging

log = logging.getLogger(__name__)
Expand All @@ -17,12 +18,15 @@ def metadata_to_dict(obj):
return str(obj)
elif hasattr(obj, "_ast"):
return metadata_to_dict(obj._ast())
elif hasattr(obj, "__iter__") and not isinstance(obj, str):
metadata = []
for item in obj:
metadata.append(metadata_to_dict(item))
return metadata
elif hasattr(obj, "__dict__"):
elif isinstance(obj, Iterable) and not isinstance(obj, str):
try:
metadata = []
for item in obj:
metadata.append(metadata_to_dict(item))
return metadata
except TypeError:
pass
if hasattr(obj, "__dict__"):
metadata = {}
for key, value in vars(obj).items():
if not callable(value) and not key.startswith('_'):
Expand Down
44 changes: 43 additions & 1 deletion tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,46 @@ def test_inject_trace_header_sampled():

inject_trace_header(headers, subsegment)

assert 'Sampled=1' in headers['X-Amzn-Trace-Id']
assert 'Sampled=1' in headers['X-Amzn-Trace-Id']

def test_metadata_to_dict_non_iterable_object():
from aws_xray_sdk.core.utils.conversion import metadata_to_dict

class MockMySQLConnection:
__iter__ = None

def __init__(self):
self.host = "localhost"
self.port = 3306
self._secret = "hidden"

conn = MockMySQLConnection()
result = metadata_to_dict(conn)
assert result == {"host": "localhost", "port": 3306}


def test_metadata_to_dict_broken_iterable():
from aws_xray_sdk.core.utils.conversion import metadata_to_dict

class BrokenIterable:
def __iter__(self):
raise TypeError("iteration failed")

def __init__(self):
self.status = "active"
self._private = 123

obj = BrokenIterable()
result = metadata_to_dict(obj)
assert result == {"status": "active"}


def test_metadata_to_dict_collection_types():
from aws_xray_sdk.core.utils.conversion import metadata_to_dict

assert metadata_to_dict({"k": "v"}) == {"k": "v"}
assert metadata_to_dict([1, "a", True]) == [1, "a", True]
assert metadata_to_dict((1, 2)) == [1, 2]
assert metadata_to_dict("text") == "text"
assert metadata_to_dict(42) == 42
assert metadata_to_dict(None) is None