Source code for cyanide.data

# -*- coding: utf-8 -*-
from __future__ import absolute_import, unicode_literals

import datetime
import decimal
import uuid

from .compat import bytes_if_py2

try:
    import simplejson as json
    from simplejson.decoder import JSONDecodeError as _DecodeError
    _json_extra_kwargs = {'use_decimal': False}
except ImportError:                 # pragma: no cover
    import json                     # noqa
    _json_extra_kwargs = {}           # noqa

    class _DecodeError(Exception):  # noqa
        pass


_encoder_cls = type(json._default_encoder)
type_registry = {}


[docs]class JSONEncoder(_encoder_cls): """Kombu custom json encoder."""
[docs] def default(self, obj, dates=(datetime.datetime, datetime.date), times=(datetime.time,), textual=(decimal.Decimal, uuid.UUID), isinstance=isinstance, datetime=datetime.datetime): try: return super(JSONEncoder, self).default(obj) except TypeError: reducer = getattr(obj, '__to_json__', None) if reducer: return reducer() if isinstance(obj, dates): if not isinstance(obj, datetime): obj = datetime(obj.year, obj.month, obj.day, 0, 0, 0, 0) r = obj.isoformat() if r.endswith("+00:00"): r = r[:-6] + "Z" return r elif isinstance(obj, times): return obj.isoformat() elif isinstance(obj, textual): return text_t(obj) raise
[docs]def decode_hook(d): try: d = d['py/obj'] except KeyError: return d type_registry[d['type']](**d['attrs'])
[docs]def install_json(): json._default_encoder = JSONEncoder() json._default_decoder.object_hook = decode_hook try: from kombu.utils import json as kombujson except ImportError: pass else: kombujson._default_encoder = JSONEncoder
install_json() # ugh, ugly but it's a test suite after all # this imports kombu.utils.json, so can only import after install_json() from celery.utils.debug import humanbytes # noqa from celery.utils.imports import qualname # noqa
[docs]def json_reduce(obj, attrs): return {'py/obj': {'type': qualname(obj), 'attrs': attrs}}
[docs]def jsonable(cls): type_registry[qualname(cls)] = cls.__from_json__ return cls
[docs]@jsonable class Data(object): def __init__(self, label, data): self.label = label self.data = data def __str__(self): return bytes_if_py2('<Data: {0} ({1})>'.format( self.label, humanbytes(len(self.data)), )) def __repr__(self): return str(self) def __to_json__(self): return json_reduce(self, {'label': self.label, 'data': self.data}) @classmethod def __from_json__(cls, label=None, data=None, **kwargs): return cls(label, data) def __reduce__(self): return Data, (self.label, self.data)
BIG = Data('BIG', 'x' * 2 ** 20 * 8) SMALL = Data('SMALL', 'e' * 1024)