Source code for reapy.tools.json

"""Encode and decode ``reapy`` objects as JSON."""

import importlib
import json
import operator
import sys


[docs]class ClassCache(dict): _core = None def __missing__(self, key): if self._core is None: # The import is here because otherwise there is an import loop # and to perform import just once. self._core = importlib.import_module("reapy.core") self[key] = getattr(self._core, key) return self[key]
_CLASS_CACHE = ClassCache()
[docs]class ReapyEncoder(json.JSONEncoder):
[docs] def default(self, x): if hasattr(x, '_to_dict'): return x._to_dict() elif callable(x): return { "__callable__": True, "module_name": x.__module__, "name": x.__qualname__ } elif isinstance(x, slice): return {"__slice__": True, "args": (x.start, x.stop, x.step)} return json.JSONEncoder.default(self, x)
[docs]def loads(s): return json.loads(s, object_hook=object_hook)
[docs]def dumps(x): return json.dumps(x, cls=ReapyEncoder)
[docs]def object_hook(x): if "__reapy__" in x: reapy_class = _CLASS_CACHE[x["class"]] return reapy_class(*x["args"], **x["kwargs"]) elif "__callable__" in x: module_name, name = x["module_name"], x["name"] try: module = sys.modules[module_name] except KeyError: module = importlib.import_module(module_name) return operator.attrgetter(name)(sys.modules[module_name]) elif "__slice__" in x: return slice(*x["args"]) else: return x