1# -*- coding: utf-8 -*- 2# 3# Copyright (C) 2009 Christopher Lenz 4# All rights reserved. 5# 6# This software is licensed as described in the file COPYING, which 7# you should have received as part of this distribution. 8 9"""Thin abstraction layer over the different available modules for decoding 10and encoding JSON data. 11 12This module currently supports the following JSON modules: 13 - ``simplejson``: http://code.google.com/p/simplejson/ 14 - ``cjson``: http://pypi.python.org/pypi/python-cjson 15 - ``json``: This is the version of ``simplejson`` that is bundled with the 16 Python standard library since version 2.6 17 (see http://docs.python.org/library/json.html) 18 19The default behavior is to use ``simplejson`` if installed, and otherwise 20fallback to the standard library module. To explicitly tell CouchDB-Python 21which module to use, invoke the `use()` function with the module name:: 22 23 from couchdb import json 24 json.use('cjson') 25 26In addition to choosing one of the above modules, you can also configure 27CouchDB-Python to use custom decoding and encoding functions:: 28 29 from couchdb import json 30 json.use(decode=my_decode, encode=my_encode) 31 32""" 33 34__all__ = ['decode', 'encode', 'use'] 35 36_initialized = False 37_using = None 38_decode = None 39_encode = None 40 41 42def decode(string): 43 """Decode the given JSON string. 44 45 :param string: the JSON string to decode 46 :type string: basestring 47 :return: the corresponding Python data structure 48 :rtype: object 49 """ 50 if not _initialized: 51 _initialize() 52 return _decode(string) 53 54 55def encode(obj): 56 """Encode the given object as a JSON string. 57 58 :param obj: the Python data structure to encode 59 :type obj: object 60 :return: the corresponding JSON string 61 :rtype: basestring 62 """ 63 if not _initialized: 64 _initialize() 65 return _encode(obj) 66 67 68def use(module=None, decode=None, encode=None): 69 """Set the JSON library that should be used, either by specifying a known 70 module name, or by providing a decode and encode function. 71 72 The modules "simplejson", "cjson", and "json" are currently supported for 73 the ``module`` parameter. 74 75 If provided, the ``decode`` parameter must be a callable that accepts a 76 JSON string and returns a corresponding Python data structure. The 77 ``encode`` callable must accept a Python data structure and return the 78 corresponding JSON string. Exceptions raised by decoding and encoding 79 should be propagated up unaltered. 80 81 :param module: the name of the JSON library module to use, or the module 82 object itself 83 :type module: str or module 84 :param decode: a function for decoding JSON strings 85 :type decode: callable 86 :param encode: a function for encoding objects as JSON strings 87 :type encode: callable 88 """ 89 global _decode, _encode, _initialized, _using 90 if module is not None: 91 if not isinstance(module, basestring): 92 module = module.__name__ 93 if module not in ('cjson', 'json', 'simplejson'): 94 raise ValueError('Unsupported JSON module %s' % module) 95 _using = module 96 _initialized = False 97 else: 98 assert decode is not None and encode is not None 99 _using = 'custom' 100 _decode = decode 101 _encode = encode 102 _initialized = True 103 104 105def _initialize(): 106 global _initialized 107 108 def _init_simplejson(): 109 global _decode, _encode 110 import simplejson 111 _decode = lambda string, loads=simplejson.loads: loads(string) 112 _encode = lambda obj, dumps=simplejson.dumps: \ 113 dumps(obj, allow_nan=False, ensure_ascii=False) 114 115 def _init_cjson(): 116 global _decode, _encode 117 import cjson 118 _decode = lambda string, decode=cjson.decode: decode(string) 119 _encode = lambda obj, encode=cjson.encode: encode(obj) 120 121 def _init_stdlib(): 122 global _decode, _encode 123 json = __import__('json', {}, {}) 124 _decode = lambda string, loads=json.loads: loads(string) 125 _encode = lambda obj, dumps=json.dumps: \ 126 dumps(obj, allow_nan=False, ensure_ascii=False) 127 128 if _using == 'simplejson': 129 _init_simplejson() 130 elif _using == 'cjson': 131 _init_cjson() 132 elif _using == 'json': 133 _init_stdlib() 134 elif _using != 'custom': 135 try: 136 _init_simplejson() 137 except ImportError: 138 _init_stdlib() 139 _initialized = True 140