1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 |
- import collections
- import json
- from django.utils.encoding import force_str
- from sentry.utils.strings import truncatechars
- SENTRY_MAX_VARIABLE_SIZE = 512
- def get_path(data, *path, **kwargs):
- """
- Safely resolves data from a recursive data structure. A value is only
- returned if the full path exists, otherwise ``None`` is returned.
- If the ``default`` argument is specified, it is returned instead of ``None``.
- If the ``filter`` argument is specified and the value is a list, it is
- filtered with the given callback. Alternatively, pass ``True`` as filter to
- only filter ``None`` values.
- """
- default = kwargs.pop("default", None)
- f = kwargs.pop("filter", None)
- for k in kwargs:
- raise TypeError("set_path() got an undefined keyword argument '%s'" % k)
- for p in path:
- if isinstance(data, collections.abc.Mapping) and p in data:
- data = data[p]
- elif isinstance(data, (list, tuple)) and -len(data) <= p < len(data):
- data = data[p]
- else:
- return default
- if f and data and isinstance(data, (list, tuple)):
- data = list(filter((lambda x: x is not None) if f is True else f, data))
- return data if data is not None else default
- def trim(
- value,
- max_size=SENTRY_MAX_VARIABLE_SIZE,
- max_depth=6,
- object_hook=None,
- _depth=0,
- _size=0,
- **kwargs,
- ):
- """
- Truncates a value to ```MAX_VARIABLE_SIZE```.
- The method of truncation depends on the type of value.
- """
- options = {
- "max_depth": max_depth,
- "max_size": max_size,
- "object_hook": object_hook,
- "_depth": _depth + 1,
- }
- if _depth > max_depth:
- if not isinstance(value, str):
- value = json.dumps(value)
- return trim(value, _size=_size, max_size=max_size)
- elif isinstance(value, dict):
- result = {}
- _size += 2
- for k in sorted(value.keys()):
- v = value[k]
- trim_v = trim(v, _size=_size, **options)
- result[k] = trim_v
- _size += len(force_str(trim_v)) + 1
- if _size >= max_size:
- break
- elif isinstance(value, (list, tuple)):
- result = []
- _size += 2
- for v in value:
- trim_v = trim(v, _size=_size, **options)
- result.append(trim_v)
- _size += len(force_str(trim_v))
- if _size >= max_size:
- break
- if isinstance(value, tuple):
- result = tuple(result)
- elif isinstance(value, str):
- result = truncatechars(value, max_size - _size)
- else:
- result = value
- if object_hook is None:
- return result
- return object_hook(result)
|