Merge pull request #509 from niphlod/fix/json_and_decimals
always stringify decimals. Better docstrings and a few PEP8.
This commit is contained in:
+39
-23
@@ -11,12 +11,19 @@ from gluon.languages import lazyT
|
|||||||
import gluon.contrib.rss2 as rss2
|
import gluon.contrib.rss2 as rss2
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import simplejson as json_parser # try external module
|
# try external module
|
||||||
|
import simplejson as json_parser
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
try:
|
||||||
import json as json_parser # try stdlib (Python >= 2.6)
|
# try stdlib (Python >= 2.6)
|
||||||
|
import json as json_parser
|
||||||
except:
|
except:
|
||||||
import gluon.contrib.simplejson as json_parser # fallback to pure-Python module
|
# fallback to pure-Python module
|
||||||
|
import gluon.contrib.simplejson as json_parser
|
||||||
|
|
||||||
|
# simplejson >= 2.1.3 needs use_decimal = False
|
||||||
|
# to stringify decimals
|
||||||
|
decimal_false_option = json_parser.__version__.split('.') >= ['2', '1', '3']
|
||||||
|
|
||||||
have_yaml = True
|
have_yaml = True
|
||||||
try:
|
try:
|
||||||
@@ -24,21 +31,23 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
have_yaml = False
|
have_yaml = False
|
||||||
|
|
||||||
|
|
||||||
def cast_keys(o, cast=str, encoding="utf-8"):
|
def cast_keys(o, cast=str, encoding="utf-8"):
|
||||||
""" Builds a new object with <cast> type keys
|
"""
|
||||||
|
Builds a new object with <cast> type keys.
|
||||||
Arguments:
|
Use this function if you are in Python < 2.6.5
|
||||||
o is the object input
|
|
||||||
cast (defaults to str) is an object type or function
|
|
||||||
which supports conversion such as:
|
|
||||||
|
|
||||||
>>> converted = cast(o)
|
|
||||||
|
|
||||||
encoding (defaults to utf-8) is the encoding for unicode
|
|
||||||
keys. This is not used for custom cast functions
|
|
||||||
|
|
||||||
Use this funcion if you are in Python < 2.6.5
|
|
||||||
This avoids syntax errors when unpacking dictionary arguments.
|
This avoids syntax errors when unpacking dictionary arguments.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
o: is the object input
|
||||||
|
cast: (defaults to str) is an object type or function
|
||||||
|
which supports conversion such as:
|
||||||
|
|
||||||
|
converted = cast(o)
|
||||||
|
|
||||||
|
encoding: (defaults to utf-8) is the encoding for unicode
|
||||||
|
keys. This is not used for custom cast functions
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if isinstance(o, (dict, Storage)):
|
if isinstance(o, (dict, Storage)):
|
||||||
@@ -65,6 +74,7 @@ def cast_keys(o, cast=str, encoding="utf-8"):
|
|||||||
newobj = o
|
newobj = o
|
||||||
return newobj
|
return newobj
|
||||||
|
|
||||||
|
|
||||||
def loads_json(o, unicode_keys=True, **kwargs):
|
def loads_json(o, unicode_keys=True, **kwargs):
|
||||||
# deserialize a json string
|
# deserialize a json string
|
||||||
result = json_parser.loads(o, **kwargs)
|
result = json_parser.loads(o, **kwargs)
|
||||||
@@ -74,6 +84,7 @@ def loads_json(o, unicode_keys=True, **kwargs):
|
|||||||
encoding=kwargs.get("encoding", "utf-8"))
|
encoding=kwargs.get("encoding", "utf-8"))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def custom_json(o):
|
def custom_json(o):
|
||||||
if hasattr(o, 'custom_json') and callable(o.custom_json):
|
if hasattr(o, 'custom_json') and callable(o.custom_json):
|
||||||
return o.custom_json()
|
return o.custom_json()
|
||||||
@@ -118,12 +129,15 @@ def xml(value, encoding='UTF-8', key='document', quote=True):
|
|||||||
|
|
||||||
|
|
||||||
def json(value, default=custom_json):
|
def json(value, default=custom_json):
|
||||||
|
if decimal_false_option:
|
||||||
|
value = json_parser.dumps(value, default=default, use_decimal=False)
|
||||||
|
else:
|
||||||
|
value = json_parser.dumps(value, default=default)
|
||||||
|
|
||||||
# replace JavaScript incompatible spacing
|
# replace JavaScript incompatible spacing
|
||||||
# http://timelessrepo.com/json-isnt-a-javascript-subset
|
# http://timelessrepo.com/json-isnt-a-javascript-subset
|
||||||
return json_parser.dumps(value,
|
return value.replace(ur'\u2028', '\\u2028').replace(ur'\2029', '\\u2029')
|
||||||
default=default).replace(ur'\u2028',
|
|
||||||
'\\u2028').replace(ur'\2029',
|
|
||||||
'\\u2029')
|
|
||||||
|
|
||||||
def csv(value):
|
def csv(value):
|
||||||
return ''
|
return ''
|
||||||
@@ -131,7 +145,6 @@ def csv(value):
|
|||||||
|
|
||||||
def ics(events, title=None, link=None, timeshift=0, calname=True,
|
def ics(events, title=None, link=None, timeshift=0, calname=True,
|
||||||
**ignored):
|
**ignored):
|
||||||
import datetime
|
|
||||||
title = title or '(unknown)'
|
title = title or '(unknown)'
|
||||||
if link and not callable(link):
|
if link and not callable(link):
|
||||||
link = lambda item, prefix=link: prefix.replace(
|
link = lambda item, prefix=link: prefix.replace(
|
||||||
@@ -183,9 +196,12 @@ def rss(feed):
|
|||||||
def yaml(data):
|
def yaml(data):
|
||||||
if have_yaml:
|
if have_yaml:
|
||||||
return yamlib.dump(data)
|
return yamlib.dump(data)
|
||||||
else: raise ImportError("No YAML serializer available")
|
else:
|
||||||
|
raise ImportError("No YAML serializer available")
|
||||||
|
|
||||||
|
|
||||||
def loads_yaml(data):
|
def loads_yaml(data):
|
||||||
if have_yaml:
|
if have_yaml:
|
||||||
return yamlib.load(data)
|
return yamlib.load(data)
|
||||||
else: raise ImportError("No YAML serializer available")
|
else:
|
||||||
|
raise ImportError("No YAML serializer available")
|
||||||
|
|||||||
Reference in New Issue
Block a user