##// END OF EJS Templates
Simplified ext_json thing, for better scope resolution in pydev
marcink -
r2528:5c8b1eaa beta
parent child Browse files
Show More
@@ -1,106 +1,111 b''
1 import datetime
1 import datetime
2 import functools
2 import functools
3 import decimal
3 import decimal
4
4
5 __all__ = ['json', 'simplejson', 'stdjson']
5 __all__ = ['json', 'simplejson', 'stdjson']
6
6
7
7
8 def _is_aware(value):
8 def _is_aware(value):
9 """
9 """
10 Determines if a given datetime.time is aware.
10 Determines if a given datetime.time is aware.
11
11
12 The logic is described in Python's docs:
12 The logic is described in Python's docs:
13 http://docs.python.org/library/datetime.html#datetime.tzinfo
13 http://docs.python.org/library/datetime.html#datetime.tzinfo
14 """
14 """
15 return (value.tzinfo is not None
15 return (value.tzinfo is not None
16 and value.tzinfo.utcoffset(value) is not None)
16 and value.tzinfo.utcoffset(value) is not None)
17
17
18
18
19 def _obj_dump(obj):
19 def _obj_dump(obj):
20 """
20 """
21 Custom function for dumping objects to JSON, if obj has __json__ attribute
21 Custom function for dumping objects to JSON, if obj has __json__ attribute
22 or method defined it will be used for serialization
22 or method defined it will be used for serialization
23
23
24 :param obj:
24 :param obj:
25 """
25 """
26
26
27 if isinstance(obj, complex):
27 if isinstance(obj, complex):
28 return [obj.real, obj.imag]
28 return [obj.real, obj.imag]
29 # See "Date Time String Format" in the ECMA-262 specification.
29 # See "Date Time String Format" in the ECMA-262 specification.
30 # some code borrowed from django 1.4
30 # some code borrowed from django 1.4
31 elif isinstance(obj, datetime.datetime):
31 elif isinstance(obj, datetime.datetime):
32 r = obj.isoformat()
32 r = obj.isoformat()
33 if obj.microsecond:
33 if obj.microsecond:
34 r = r[:23] + r[26:]
34 r = r[:23] + r[26:]
35 if r.endswith('+00:00'):
35 if r.endswith('+00:00'):
36 r = r[:-6] + 'Z'
36 r = r[:-6] + 'Z'
37 return r
37 return r
38 elif isinstance(obj, datetime.date):
38 elif isinstance(obj, datetime.date):
39 return obj.isoformat()
39 return obj.isoformat()
40 elif isinstance(obj, decimal.Decimal):
40 elif isinstance(obj, decimal.Decimal):
41 return str(obj)
41 return str(obj)
42 elif isinstance(obj, datetime.time):
42 elif isinstance(obj, datetime.time):
43 if _is_aware(obj):
43 if _is_aware(obj):
44 raise ValueError("JSON can't represent timezone-aware times.")
44 raise ValueError("JSON can't represent timezone-aware times.")
45 r = obj.isoformat()
45 r = obj.isoformat()
46 if obj.microsecond:
46 if obj.microsecond:
47 r = r[:12]
47 r = r[:12]
48 return r
48 return r
49 elif isinstance(obj, set):
49 elif isinstance(obj, set):
50 return list(obj)
50 return list(obj)
51 elif hasattr(obj, '__json__'):
51 elif hasattr(obj, '__json__'):
52 if callable(obj.__json__):
52 if callable(obj.__json__):
53 return obj.__json__()
53 return obj.__json__()
54 else:
54 else:
55 return obj.__json__
55 return obj.__json__
56 else:
56 else:
57 raise NotImplementedError
57 raise NotImplementedError
58
58
59
59
60 # Import simplejson
60 # Import simplejson
61 try:
61 try:
62 # import simplejson initially
62 # import simplejson initially
63 import simplejson as _sj
63 import simplejson
64
64
65 def extended_encode(obj):
65 def extended_encode(obj):
66 try:
66 try:
67 return _obj_dump(obj)
67 return _obj_dump(obj)
68 except NotImplementedError:
68 except NotImplementedError:
69 pass
69 pass
70 raise TypeError("%r is not JSON serializable" % (obj,))
70 raise TypeError("%r is not JSON serializable" % (obj,))
71 # we handle decimals our own it makes unified behavior of json vs
71 # we handle decimals our own it makes unified behavior of json vs
72 # simplejson
72 # simplejson
73 _sj.dumps = functools.partial(_sj.dumps, default=extended_encode,
73 simplejson.dumps = functools.partial(simplejson.dumps,
74 use_decimal=False)
74 default=extended_encode,
75 _sj.dump = functools.partial(_sj.dump, default=extended_encode,
75 use_decimal=False)
76 use_decimal=False)
76 simplejson.dump = functools.partial(simplejson.dump,
77 simplejson = _sj
77 default=extended_encode,
78
78 use_decimal=False)
79 except ImportError:
79 except ImportError:
80 # no simplejson set it to None
80 # no simplejson set it to None
81 _sj = None
81 simplejson = None
82
82
83
83
84 try:
84 try:
85 # simplejson not found try out regular json module
85 # simplejson not found try out regular json module
86 import json as _json
86 import json
87
87
88 # extended JSON encoder for json
88 # extended JSON encoder for json
89 class ExtendedEncoder(_json.JSONEncoder):
89 class ExtendedEncoder(json.JSONEncoder):
90 def default(self, obj):
90 def default(self, obj):
91 try:
91 try:
92 return _obj_dump(obj)
92 return _obj_dump(obj)
93 except NotImplementedError:
93 except NotImplementedError:
94 pass
94 pass
95 return _json.JSONEncoder.default(self, obj)
95 return json.JSONEncoder.default(self, obj)
96 # monkey-patch JSON encoder to use extended version
96 # monkey-patch JSON encoder to use extended version
97 _json.dumps = functools.partial(_json.dumps, cls=ExtendedEncoder)
97 json.dumps = functools.partial(json.dumps, cls=ExtendedEncoder)
98 _json.dump = functools.partial(_json.dump, cls=ExtendedEncoder)
98 json.dump = functools.partial(json.dump, cls=ExtendedEncoder)
99 stdlib = _json
99
100 except ImportError:
100 except ImportError:
101 _json = None
101 json = None
102
103 stdlib = json
102
104
103 # set all available json modules
105 # set all available json modules
104 simplejson = _sj
106 if simplejson:
105 stdjson = _json
107 json = simplejson
106 json = _sj if _sj else _json
108 elif json:
109 json = json
110 else:
111 raise ImportError('Could not find any json modules')
General Comments 0
You need to be logged in to leave comments. Login now