summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchebee7i <chebee7i@gmail.com>2018-03-08 15:09:20 -0600
committerAshley Camba <ashwoods@gmail.com>2018-05-02 19:36:28 +0200
commitf31e4042d8f1fbdc7c23ed37547516d28a7c846a (patch)
treed482584eb4e0c6677e61dd5976c71c76d65f2ac4
parent8904c3ba7c87103e4aaac86bc84ad2233378ba6f (diff)
downloadraven-f31e4042d8f1fbdc7c23ed37547516d28a7c846a.tar.gz
Make BetterJSONEncoder use OrderedDict for namedtuples.
-rw-r--r--raven/utils/basic.py10
-rw-r--r--raven/utils/json.py13
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)