|
8 | 8 | """ |
9 | 9 | from __future__ import absolute_import |
10 | 10 |
|
| 11 | +import collections |
11 | 12 | import itertools |
12 | 13 | import types |
13 | 14 |
|
14 | 15 | from raven.utils.compat import text_type, binary_type, string_types, iteritems, \ |
15 | 16 | class_types, PY2, PY3 |
16 | 17 | from raven.utils.encoding import to_unicode |
17 | 18 | from .manager import manager as serialization_manager |
| 19 | +from raven.utils import is_namedtuple |
| 20 | + |
18 | 21 |
|
19 | 22 | __all__ = ('Serializer',) |
20 | 23 |
|
@@ -65,6 +68,28 @@ def recurse(self, value, max_depth=6, _depth=0, **kwargs): |
65 | 68 | _depth=_depth, **kwargs) |
66 | 69 |
|
67 | 70 |
|
| 71 | +class NamedtupleSerializer(Serializer): |
| 72 | + types = (collections.namedtuple,) |
| 73 | + |
| 74 | + def can(self, value): |
| 75 | + """ |
| 76 | + Given ``value``, return a boolean describing whether this |
| 77 | + serializer can operate on the given type |
| 78 | + """ |
| 79 | + return is_namedtuple(value) |
| 80 | + |
| 81 | + def serialize(self, value, **kwargs): |
| 82 | + list_max_length = kwargs.get('list_max_length') or float('inf') |
| 83 | + less_than = lambda x: x[0] < list_max_length |
| 84 | + items = value._asdict().items() |
| 85 | + takewhile = itertools.takewhile |
| 86 | + x = dict([ |
| 87 | + (k, self.recurse(v, **kwargs)) |
| 88 | + for n, (k, v) in takewhile(less_than, enumerate(items)) |
| 89 | + ]) |
| 90 | + return x |
| 91 | + |
| 92 | + |
68 | 93 | class IterableSerializer(Serializer): |
69 | 94 | types = (tuple, list, set, frozenset) |
70 | 95 |
|
@@ -176,6 +201,7 @@ def serialize(self, value, **kwargs): |
176 | 201 |
|
177 | 202 |
|
178 | 203 | # register all serializers, order matters |
| 204 | +serialization_manager.register(NamedtupleSerializer) |
179 | 205 | serialization_manager.register(IterableSerializer) |
180 | 206 | serialization_manager.register(DictSerializer) |
181 | 207 | serialization_manager.register(UnicodeSerializer) |
|
0 commit comments