##// END OF EJS Templates
Fixed simplejson import on python 2.5
marcink -
r2258:8a3a1a59 beta
parent child Browse files
Show More
@@ -1,104 +1,106 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 as _sj
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 _sj.dumps = functools.partial(_sj.dumps, default=extended_encode,
74 use_decimal=False)
74 use_decimal=False)
75 _sj.dump = functools.partial(_sj.dump, default=extended_encode,
75 _sj.dump = functools.partial(_sj.dump, default=extended_encode,
76 use_decimal=False)
76 use_decimal=False)
77 simplejson = _sj
77 simplejson = _sj
78
78
79 except ImportError:
79 except ImportError:
80 # no simplejson set it to None
80 # no simplejson set it to None
81 _sj = None
81 _sj = None
82
82
83
83
84 # simplejson not found try out regular json module
84 try:
85 import json as _json
85 # simplejson not found try out regular json module
86
86 import json as _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 stdlib = _json
100 except ImportError:
101 _json = None
100
102
101 # set all available json modules
103 # set all available json modules
102 simplejson = _sj
104 simplejson = _sj
103 stdjson = _json
105 stdjson = _json
104 json = _sj if _sj else _json
106 json = _sj if _sj else _json
General Comments 0
You need to be logged in to leave comments. Login now