Source code for transit.write_handlers
## Copyright 2014 Cognitect. All Rights Reserved.
##
## Licensed under the Apache License, Version 2.0 (the "License");
## you may not use this file except in compliance with the License.
## You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS-IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
import uuid
import datetime
import struct
from class_hash import ClassDict
from transit_types import Keyword, Symbol, URI, frozendict, TaggedValue, Link, Boolean
from decimal import Decimal
from dateutil import tz
from math import isnan
## This file contains Write Handlers - all the top-level objects used when
## writing Transit data. These object must all be immutable and pickleable.
[docs]class TaggedMap(object):
def __init__(self, tag, rep, str):
self._tag = tag
self._rep = rep
self._str = str
[docs] def tag(self):
return self._tag
[docs] def rep(self):
return self._rep
[docs] def string_rep(self):
return self._str
[docs]class NoneHandler(object):
@staticmethod
@staticmethod
[docs] def rep(_):
return None
@staticmethod
[docs] def string_rep(n):
return None
[docs]class IntHandler(object):
@staticmethod
@staticmethod
@staticmethod
[docs] def string_rep(i):
return str(i)
[docs]class BigIntHandler(object):
@staticmethod
@staticmethod
[docs] def rep(n):
return str(n)
@staticmethod
[docs] def string_rep(n):
return str(n)
[docs]class BigDecimalHandler(object):
@staticmethod
@staticmethod
[docs] def rep(n):
return str(n)
@staticmethod
[docs] def string_rep(n):
return str(n)
[docs]class FloatHandler(object):
@staticmethod
[docs] def tag(f):
return "z" if isnan(f) or f in (float('Inf'), float('-Inf')) else "d"
@staticmethod
[docs] def rep(f):
if isnan(f):
return "NaN"
if f == float('Inf'):
return "INF"
if f == float("-Inf"):
return "-INF"
return f
@staticmethod
[docs] def string_rep(f):
return str(f)
[docs]class StringHandler(object):
@staticmethod
@staticmethod
@staticmethod
[docs] def string_rep(s):
return s
[docs]class BooleanHandler(object):
@staticmethod
@staticmethod
[docs] def rep(b):
return bool(b)
@staticmethod
[docs] def string_rep(b):
return 't' if b else 'f'
[docs]class ArrayHandler(object):
@staticmethod
[docs] def tag(a):
return 'array'
@staticmethod
@staticmethod
[docs] def string_rep(a):
return None
[docs]class MapHandler(object):
@staticmethod
[docs] def tag(m):
return 'map'
@staticmethod
@staticmethod
[docs] def string_rep(m):
return None
[docs]class KeywordHandler(object):
@staticmethod
@staticmethod
[docs] def rep(k):
return str(k)
@staticmethod
[docs] def string_rep(k):
return str(k)
[docs]class SymbolHandler(object):
@staticmethod
@staticmethod
[docs] def rep(s):
return str(s)
@staticmethod
[docs] def string_rep(s):
return str(s)
[docs]class UuidHandler(object):
@staticmethod
@staticmethod
[docs] def rep(u):
return struct.unpack('>qq', u.bytes)
@staticmethod
[docs] def string_rep(u):
return str(u)
[docs]class UriHandler(object):
@staticmethod
@staticmethod
[docs] def rep(u):
return u.rep
@staticmethod
[docs] def string_rep(u):
return u.rep
[docs]class DateTimeHandler(object):
epoch = datetime.datetime(1970, 1, 1).replace(tzinfo=tz.tzutc())
@staticmethod
@staticmethod
[docs] def rep(d):
td = d - DateTimeHandler.epoch
return int((td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 1e3)
@staticmethod
[docs] def verbose_handler():
return VerboseDateTimeHandler
@staticmethod
[docs] def string_rep(d):
return str(DateTimeHandler.rep(d))
[docs]class VerboseDateTimeHandler(object):
@staticmethod
@staticmethod
[docs] def rep(d):
return d.isoformat()
@staticmethod
[docs] def string_rep(d):
return d.isoformat()
[docs]class SetHandler(object):
@staticmethod
[docs] def tag(_):
return "set"
@staticmethod
[docs] def rep(s):
return TaggedMap("array", tuple(s), None)
@staticmethod
[docs] def string_rep(_):
return None
[docs]class TaggedValueHandler(object):
@staticmethod
[docs] def tag(tv):
return tv.tag
@staticmethod
[docs] def rep(tv):
return tv.rep
@staticmethod
[docs] def string_rep(_):
return None
[docs]class LinkHandler(object):
@staticmethod
[docs] def tag(_):
return "link"
@staticmethod
[docs] def rep(l):
return l.as_map
@staticmethod
[docs] def string_rep(_):
return None
[docs]class WriteHandler(ClassDict):
"""This is the master handler for encoding/writing Python data into
Transit data, based on its type.
The Handler itself is a dispatch map, that resolves on full type/object
inheritance.
These handlers can be overriden during the creation of a Transit Writer.
"""
def __init__(self):
super(WriteHandler, self).__init__()
self[type(None)] = NoneHandler
self[bool] = BooleanHandler
self[Boolean] = BooleanHandler
self[str] = StringHandler
self[unicode] = StringHandler
self[list] = ArrayHandler
self[tuple] = ArrayHandler
self[dict] = MapHandler
self[int] = IntHandler
self[float] = FloatHandler
self[long] = BigIntHandler
self[Keyword] = KeywordHandler
self[Symbol] = SymbolHandler
self[uuid.UUID] = UuidHandler
self[URI] = UriHandler
self[datetime.datetime] = DateTimeHandler
self[set] = SetHandler
self[frozenset] = SetHandler
self[TaggedMap] = TaggedMap
self[dict] = MapHandler
self[frozendict] = MapHandler
self[TaggedValue] = TaggedValueHandler
self[Link] = LinkHandler
self[Decimal] = BigDecimalHandler