##// END OF EJS Templates
ini: added new key
ini: added new key

File last commit:

r112:998f0d14
r129:489ce37b
Show More
ext_json.py
148 lines | 4.2 KiB | text/x-python | PythonLexer
# -*- coding: utf-8 -*-
# Copyright 2010 - 2017 RhodeCode GmbH and the AppEnlight project authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
ex-json borrowed from Marcin Kuzminski
source: https://secure.rhodecode.org/ext-json
"""
import datetime
import functools
import decimal
import imp
__all__ = ['json', 'simplejson', 'stdlibjson']
def _is_aware(value):
"""
Determines if a given datetime.time is aware.
The logic is described in Python's docs:
http://docs.python.org/library/datetime.html#datetime.tzinfo
"""
return (value.tzinfo is not None
and value.tzinfo.utcoffset(value) is not None)
def _obj_dump(obj):
"""
Custom function for dumping objects to JSON, if obj has __json__ attribute
or method defined it will be used for serialization
:param obj:
"""
if isinstance(obj, complex):
return [obj.real, obj.imag]
# See "Date Time String Format" in the ECMA-262 specification.
# some code borrowed from django 1.4
elif isinstance(obj, datetime.datetime):
r = obj.isoformat()
# if obj.microsecond:
# r = r[:23] + r[26:]
if r.endswith('+00:00'):
r = r[:-6] + 'Z'
return r
elif isinstance(obj, datetime.date):
return obj.isoformat()
elif isinstance(obj, decimal.Decimal):
return str(obj)
elif isinstance(obj, datetime.time):
if _is_aware(obj):
raise ValueError("JSON can't represent timezone-aware times.")
r = obj.isoformat()
if obj.microsecond:
r = r[:12]
return r
elif isinstance(obj, set):
return list(obj)
elif hasattr(obj, '__json__'):
if callable(obj.__json__):
return obj.__json__()
else:
return obj.__json__
else:
raise NotImplementedError
# Import simplejson
try:
# import simplejson initially
_sj = imp.load_module('_sj', *imp.find_module('simplejson'))
def extended_encode(obj):
try:
return _obj_dump(obj)
except NotImplementedError:
pass
raise TypeError("%r is not JSON serializable" % (obj,))
# we handle decimals our own it makes unified behavior of json vs
# simplejson
sj_version = [int(x) for x in _sj.__version__.split('.')]
major, minor = sj_version[0], sj_version[1]
if major < 2 or (major == 2 and minor < 1):
# simplejson < 2.1 doesnt support use_decimal
_sj.dumps = functools.partial(
_sj.dumps, default=extended_encode)
_sj.dump = functools.partial(
_sj.dump, default=extended_encode)
else:
_sj.dumps = functools.partial(
_sj.dumps, default=extended_encode, use_decimal=False)
_sj.dump = functools.partial(
_sj.dump, default=extended_encode, use_decimal=False)
simplejson = _sj
except ImportError:
# no simplejson set it to None
simplejson = None
try:
# simplejson not found try out regular json module
_json = imp.load_module('_json', *imp.find_module('json'))
# extended JSON encoder for json
class ExtendedEncoder(_json.JSONEncoder):
def default(self, obj):
try:
return _obj_dump(obj)
except NotImplementedError:
pass
raise TypeError("%r is not JSON serializable" % (obj,))
# monkey-patch JSON encoder to use extended version
_json.dumps = functools.partial(_json.dumps, cls=ExtendedEncoder)
_json.dump = functools.partial(_json.dump, cls=ExtendedEncoder)
except ImportError:
json = None
stdlibjson = _json
# set all available json modules
if simplejson:
json = _sj
elif _json:
json = _json
else:
raise ImportError('Could not find any json modules')