in elasticapm/utils/encoding.py [0:0]
def transform(value, stack=None, context=None):
# TODO: make this extendable
if context is None:
context = {}
if stack is None:
stack = []
objid = id(value)
if objid in context:
return "<...>"
context[objid] = 1
transform_rec = lambda o: transform(o, stack + [value], context)
if any(value is s for s in stack):
ret = "cycle"
elif isinstance(value, (tuple, list, set, frozenset)):
try:
ret = type(value)(transform_rec(o) for o in value)
except Exception:
# We may be dealing with a namedtuple
class value_type(list):
__name__ = type(value).__name__
ret = value_type(transform_rec(o) for o in value)
elif isinstance(value, uuid.UUID):
try:
ret = repr(value)
except AttributeError:
ret = None
elif isinstance(value, dict):
# iterate over a copy of the dictionary to avoid "dictionary changed size during iteration" issues
ret = dict((to_unicode(k), transform_rec(v)) for k, v in value.copy().items())
elif isinstance(value, str):
ret = to_unicode(value)
elif isinstance(value, bytes):
ret = to_string(value)
elif not isinstance(value, type) and _has_elasticapm_metadata(value):
ret = transform_rec(value.__elasticapm__())
elif isinstance(value, bool):
ret = bool(value)
elif isinstance(value, float):
ret = float(value)
elif isinstance(value, int):
ret = int(value)
elif value is not None:
try:
ret = transform(repr(value))
except Exception:
# It's common case that a model's __unicode__ definition may try to query the database
# which if it was not cleaned up correctly, would hit a transaction aborted exception
ret = "<BadRepr: %s>" % type(value)
else:
ret = None
del context[objid]
return ret