Source

jaraco.json / jaraco / json / main.py

Full commit
from __future__ import absolute_import
# http://docs.python.org/library/json.html
import json

class GenericEncoder(json.JSONEncoder):
	"""
	A JSON encoder that encodes any Python object similar to how
	the pickle module works.
	"""
	def default(self, object):
		# use the pickle protocol 2 to serialize the object
		reduced = object.__reduce_ex__(2)
		return self.save_reduce(*reduced, obj = object)

	def save_reduce(self, func, args, state, listitems=None,
		dictitems=None, obj=None):
		"""
		generate a JSON representation of this object's reduce_ex
		result.
		"""
		cls, args = args[0], args[1:]
		return dict(
			__python_class__ = cls.__name__,
			__python_module__ = cls.__module__,
			args = self.encode(args),
			state = self.encode(state),
			)

encode = GenericEncoder().encode

def _find_module_by_name(mod_name):
	mod_sep = '.'
	parent = __import__(mod_name)
	parent_name, sep, children = mod_name.partition(mod_sep)
	if not children: return parent
	for child in children.split(mod_sep):
		parent = getattr(parent, child)
	return parent

def decode_object_hook(object):
	if '__python_class__' not in object.keys():
		return object
	class_name = object['__python_class__']
	mod_name = object['__python_module__']
	args = decode(object['args'])
	state = decode(object['state'])
	mod = _find_module_by_name(mod_name)
	cls = getattr(mod, class_name)
	ob = cls.__new__(cls, *args)
	ob.__dict__.update(state)
	return ob

decode = json.JSONDecoder(object_hook = decode_object_hook).decode