diff options
author | chebee7i <chebee7i@gmail.com> | 2018-03-08 15:09:20 -0600 |
---|---|---|
committer | Ashley Camba <ashwoods@gmail.com> | 2018-05-02 19:36:28 +0200 |
commit | f31e4042d8f1fbdc7c23ed37547516d28a7c846a (patch) | |
tree | d482584eb4e0c6677e61dd5976c71c76d65f2ac4 | |
parent | 8904c3ba7c87103e4aaac86bc84ad2233378ba6f (diff) | |
download | raven-f31e4042d8f1fbdc7c23ed37547516d28a7c846a.tar.gz |
Make BetterJSONEncoder use OrderedDict for namedtuples.
-rw-r--r-- | raven/utils/basic.py | 10 | ||||
-rw-r--r-- | raven/utils/json.py | 13 |
2 files changed, 19 insertions, 4 deletions
diff --git a/raven/utils/basic.py b/raven/utils/basic.py index d995423..3342c1b 100644 --- a/raven/utils/basic.py +++ b/raven/utils/basic.py @@ -1,5 +1,11 @@ from __future__ import absolute_import +try: + from collections.abc import Mapping +except ImportError: + # Python < 3.3 + from collections import Mapping + from functools import update_wrapper import threading @@ -30,11 +36,11 @@ def varmap(func, var, context=None, name=None): return func(name, '<...>') context[objid] = 1 - if isinstance(var, (list, tuple)): + if isinstance(var, (list, tuple)) and not is_namedtuple(var): ret = [varmap(func, f, context, name) for f in var] else: ret = func(name, var) - if isinstance(ret, dict): + if isinstance(ret, Mapping): ret = dict((k, varmap(func, v, context, k)) for k, v in iteritems(var)) del context[objid] diff --git a/raven/utils/json.py b/raven/utils/json.py index d88cdc7..ef8fe25 100644 --- a/raven/utils/json.py +++ b/raven/utils/json.py @@ -9,10 +9,14 @@ raven.utils.json from __future__ import absolute_import import codecs +import collections import datetime import uuid import json +from .basic import is_namedtuple + + try: JSONDecodeError = json.JSONDecodeError except AttributeError: @@ -25,12 +29,17 @@ class BetterJSONEncoder(json.JSONEncoder): datetime.datetime: lambda o: o.strftime('%Y-%m-%dT%H:%M:%SZ'), set: list, frozenset: list, - bytes: lambda o: o.decode('utf-8', errors='replace') + bytes: lambda o: o.decode('utf-8', errors='replace'), + collections.namedtuple: lambda o: o._asdict(), } def default(self, obj): + obj_type = type(obj) + if obj_type not in self.ENCODER_BY_TYPE and is_namedtuple(obj): + obj_type = collections.namedtuple + try: - encoder = self.ENCODER_BY_TYPE[type(obj)] + encoder = self.ENCODER_BY_TYPE[obj_type] except KeyError: try: return super(BetterJSONEncoder, self).default(obj) |