Mercurial > kallithea
annotate rhodecode/lib/ext_json.py @ 3882:2c5ceb546234 beta
renamed gists routing to proper plural names
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Mon, 20 May 2013 21:40:00 +0200 |
parents | 685ebc84c2e9 |
children |
rev | line source |
---|---|
2173 | 1 import datetime |
2 import functools | |
3 import decimal | |
3013
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
4 import imp |
2173 | 5 |
3013
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
6 __all__ = ['json', 'simplejson', 'stdlibjson'] |
2173 | 7 |
8 | |
9 def _is_aware(value): | |
10 """ | |
11 Determines if a given datetime.time is aware. | |
12 | |
13 The logic is described in Python's docs: | |
14 http://docs.python.org/library/datetime.html#datetime.tzinfo | |
15 """ | |
16 return (value.tzinfo is not None | |
17 and value.tzinfo.utcoffset(value) is not None) | |
18 | |
19 | |
20 def _obj_dump(obj): | |
21 """ | |
22 Custom function for dumping objects to JSON, if obj has __json__ attribute | |
23 or method defined it will be used for serialization | |
24 | |
25 :param obj: | |
26 """ | |
27 | |
28 if isinstance(obj, complex): | |
29 return [obj.real, obj.imag] | |
30 # See "Date Time String Format" in the ECMA-262 specification. | |
31 # some code borrowed from django 1.4 | |
32 elif isinstance(obj, datetime.datetime): | |
33 r = obj.isoformat() | |
34 if obj.microsecond: | |
35 r = r[:23] + r[26:] | |
36 if r.endswith('+00:00'): | |
37 r = r[:-6] + 'Z' | |
38 return r | |
39 elif isinstance(obj, datetime.date): | |
40 return obj.isoformat() | |
41 elif isinstance(obj, decimal.Decimal): | |
42 return str(obj) | |
43 elif isinstance(obj, datetime.time): | |
44 if _is_aware(obj): | |
45 raise ValueError("JSON can't represent timezone-aware times.") | |
46 r = obj.isoformat() | |
47 if obj.microsecond: | |
48 r = r[:12] | |
49 return r | |
50 elif isinstance(obj, set): | |
51 return list(obj) | |
52 elif hasattr(obj, '__json__'): | |
53 if callable(obj.__json__): | |
54 return obj.__json__() | |
55 else: | |
56 return obj.__json__ | |
57 else: | |
58 raise NotImplementedError | |
59 | |
60 | |
61 # Import simplejson | |
62 try: | |
63 # import simplejson initially | |
3013
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
64 _sj = imp.load_module('_sj', *imp.find_module('simplejson')) |
2173 | 65 |
66 def extended_encode(obj): | |
67 try: | |
68 return _obj_dump(obj) | |
69 except NotImplementedError: | |
70 pass | |
71 raise TypeError("%r is not JSON serializable" % (obj,)) | |
2174
85a64b981c07
ws cleanup, +changelog
Marcin Kuzminski <marcin@python-works.com>
parents:
2173
diff
changeset
|
72 # we handle decimals our own it makes unified behavior of json vs |
2173 | 73 # simplejson |
3013
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
74 sj_version = [int(x) for x in _sj.__version__.split('.')] |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
75 major, minor = sj_version[0], sj_version[1] |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
76 if major < 2 or (major == 2 and minor < 1): |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
77 # simplejson < 2.1 doesnt support use_decimal |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
78 _sj.dumps = functools.partial(_sj.dumps, |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
79 default=extended_encode) |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
80 _sj.dump = functools.partial(_sj.dump, |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
81 default=extended_encode) |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
82 else: |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
83 _sj.dumps = functools.partial(_sj.dumps, |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
84 default=extended_encode, |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
85 use_decimal=False) |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
86 _sj.dump = functools.partial(_sj.dump, |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
87 default=extended_encode, |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
88 use_decimal=False) |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
89 simplejson = _sj |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
90 |
2173 | 91 except ImportError: |
92 # no simplejson set it to None | |
2528
5c8b1eaafe77
Simplified ext_json thing, for better scope resolution in pydev
Marcin Kuzminski <marcin@python-works.com>
parents:
2258
diff
changeset
|
93 simplejson = None |
2173 | 94 |
95 | |
2258
8a3a1a59a050
Fixed simplejson import on python 2.5
Marcin Kuzminski <marcin@python-works.com>
parents:
2174
diff
changeset
|
96 try: |
8a3a1a59a050
Fixed simplejson import on python 2.5
Marcin Kuzminski <marcin@python-works.com>
parents:
2174
diff
changeset
|
97 # simplejson not found try out regular json module |
3013
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
98 _json = imp.load_module('_json', *imp.find_module('json')) |
2173 | 99 |
2258
8a3a1a59a050
Fixed simplejson import on python 2.5
Marcin Kuzminski <marcin@python-works.com>
parents:
2174
diff
changeset
|
100 # extended JSON encoder for json |
3013
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
101 class ExtendedEncoder(_json.JSONEncoder): |
2258
8a3a1a59a050
Fixed simplejson import on python 2.5
Marcin Kuzminski <marcin@python-works.com>
parents:
2174
diff
changeset
|
102 def default(self, obj): |
8a3a1a59a050
Fixed simplejson import on python 2.5
Marcin Kuzminski <marcin@python-works.com>
parents:
2174
diff
changeset
|
103 try: |
8a3a1a59a050
Fixed simplejson import on python 2.5
Marcin Kuzminski <marcin@python-works.com>
parents:
2174
diff
changeset
|
104 return _obj_dump(obj) |
8a3a1a59a050
Fixed simplejson import on python 2.5
Marcin Kuzminski <marcin@python-works.com>
parents:
2174
diff
changeset
|
105 except NotImplementedError: |
8a3a1a59a050
Fixed simplejson import on python 2.5
Marcin Kuzminski <marcin@python-works.com>
parents:
2174
diff
changeset
|
106 pass |
2817
3ae42e10b665
fix ext-json extension issue when exception is raised for non-serializable objects
Marcin Kuzminski <marcin@python-works.com>
parents:
2528
diff
changeset
|
107 raise TypeError("%r is not JSON serializable" % (obj,)) |
2258
8a3a1a59a050
Fixed simplejson import on python 2.5
Marcin Kuzminski <marcin@python-works.com>
parents:
2174
diff
changeset
|
108 # monkey-patch JSON encoder to use extended version |
3013
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
109 _json.dumps = functools.partial(_json.dumps, cls=ExtendedEncoder) |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
110 _json.dump = functools.partial(_json.dump, cls=ExtendedEncoder) |
2528
5c8b1eaafe77
Simplified ext_json thing, for better scope resolution in pydev
Marcin Kuzminski <marcin@python-works.com>
parents:
2258
diff
changeset
|
111 |
3013
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
112 stdlibjson = _json |
2258
8a3a1a59a050
Fixed simplejson import on python 2.5
Marcin Kuzminski <marcin@python-works.com>
parents:
2174
diff
changeset
|
113 except ImportError: |
3013
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
114 stdlibjson = None |
2173 | 115 |
116 # set all available json modules | |
2528
5c8b1eaafe77
Simplified ext_json thing, for better scope resolution in pydev
Marcin Kuzminski <marcin@python-works.com>
parents:
2258
diff
changeset
|
117 if simplejson: |
3013
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
118 json = _sj |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
119 elif stdlibjson: |
83159d73b13b
merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents:
2817
diff
changeset
|
120 json = _json |
2528
5c8b1eaafe77
Simplified ext_json thing, for better scope resolution in pydev
Marcin Kuzminski <marcin@python-works.com>
parents:
2258
diff
changeset
|
121 else: |
3029
685ebc84c2e9
White space cleanup
Marcin Kuzminski <marcin@python-works.com>
parents:
3013
diff
changeset
|
122 raise ImportError('Could not find any json modules') |