annotate rhodecode/lib/ext_json.py @ 4116:ffd45b185016 rhodecode-2.2.5-gpl

Imported some of the GPLv3'd changes from RhodeCode v2.2.5. This imports changes between changesets 21af6c4eab3d and 6177597791c2 in RhodeCode's original repository, including only changes to Python files and HTML. RhodeCode clearly licensed its changes to these files under GPLv3 in their /LICENSE file, which states the following: The Python code and integrated HTML are licensed under the GPLv3 license. (See: https://code.rhodecode.com/rhodecode/files/v2.2.5/LICENSE or http://web.archive.org/web/20140512193334/https://code.rhodecode.com/rhodecode/files/f3b123159901f15426d18e3dc395e8369f70ebe0/LICENSE for an online copy of that LICENSE file) Conservancy reviewed these changes and confirmed that they can be licensed as a whole to the Kallithea project under GPLv3-only. While some of the contents committed herein are clearly licensed GPLv3-or-later, on the whole we must assume the are GPLv3-only, since the statement above from RhodeCode indicates that they intend GPLv3-only as their license, per GPLv3ยง14 and other relevant sections of GPLv3.
author Bradley M. Kuhn <bkuhn@sfconservancy.org>
date Wed, 02 Jul 2014 19:03:13 -0400
parents 685ebc84c2e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
2173
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
1 import datetime
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
2 import functools
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
3 import decimal
3013
83159d73b13b merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents: 2817
diff changeset
4 import imp
2173
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
5
3013
83159d73b13b merge ext_json with upstream
Marcin Kuzminski <marcin@python-works.com>
parents: 2817
diff changeset
6 __all__ = ['json', 'simplejson', 'stdlibjson']
2173
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
7
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
8
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
9 def _is_aware(value):
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
10 """
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
11 Determines if a given datetime.time is aware.
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
12
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
13 The logic is described in Python's docs:
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
14 http://docs.python.org/library/datetime.html#datetime.tzinfo
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
15 """
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
16 return (value.tzinfo is not None
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
17 and value.tzinfo.utcoffset(value) is not None)
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
18
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
19
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
20 def _obj_dump(obj):
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
21 """
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
22 Custom function for dumping objects to JSON, if obj has __json__ attribute
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
23 or method defined it will be used for serialization
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
24
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
25 :param obj:
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
26 """
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
27
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
28 if isinstance(obj, complex):
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
29 return [obj.real, obj.imag]
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
30 # See "Date Time String Format" in the ECMA-262 specification.
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
31 # some code borrowed from django 1.4
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
32 elif isinstance(obj, datetime.datetime):
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
33 r = obj.isoformat()
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
34 if obj.microsecond:
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
35 r = r[:23] + r[26:]
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
36 if r.endswith('+00:00'):
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
37 r = r[:-6] + 'Z'
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
38 return r
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
39 elif isinstance(obj, datetime.date):
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
40 return obj.isoformat()
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
41 elif isinstance(obj, decimal.Decimal):
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
42 return str(obj)
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
43 elif isinstance(obj, datetime.time):
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
44 if _is_aware(obj):
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
45 raise ValueError("JSON can't represent timezone-aware times.")
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
46 r = obj.isoformat()
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
47 if obj.microsecond:
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
48 r = r[:12]
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
49 return r
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
50 elif isinstance(obj, set):
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
51 return list(obj)
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
52 elif hasattr(obj, '__json__'):
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
53 if callable(obj.__json__):
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
54 return obj.__json__()
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
55 else:
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
56 return obj.__json__
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
57 else:
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
58 raise NotImplementedError
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
59
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
60
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
61 # Import simplejson
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
62 try:
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
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
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
65
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
66 def extended_encode(obj):
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
67 try:
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
68 return _obj_dump(obj)
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
69 except NotImplementedError:
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
70 pass
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
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
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
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
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
91 except ImportError:
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
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
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
94
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
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
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
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
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
115
775a7672d363 add ext_json module
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
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')