transit-python 0.8.174-__py2-none-any.whl → 0.8.240__py2-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
scratch/__init__.py ADDED
@@ -0,0 +1 @@
1
+ # empty
scratch/bools.py ADDED
@@ -0,0 +1,15 @@
1
+ from transit.transit_types import true, false
2
+
3
+
4
+ if true:
5
+ print("ok")
6
+ if not true:
7
+ print("not ok")
8
+ if false:
9
+ print("not ok")
10
+ if not false:
11
+ print("ok")
12
+ if true and false:
13
+ print("not ok")
14
+ if true or false:
15
+ print("ok")
@@ -0,0 +1,10 @@
1
+ from StringIO import StringIO
2
+ from transit.writer import Writer
3
+ from transit.reader import Reader
4
+ from transit.transit_types import Symbol
5
+ r = Reader('json')
6
+ io = StringIO()
7
+ w = Writer(io,'json')
8
+ w.write([{"Problem?":True},Symbol("Here"),Symbol("Here")])
9
+ print(io.getvalue())
10
+ print(r.read(StringIO(io.getvalue())))
scratch/dt.py ADDED
@@ -0,0 +1,7 @@
1
+ from transit.writer import Writer
2
+ from StringIO import StringIO
3
+ import datetime as dt
4
+
5
+ io = StringIO()
6
+ writer = Writer(io, "json")
7
+ writer.write({"date": dt.datetime.utcnow()})
scratch/emptyset.py ADDED
@@ -0,0 +1,19 @@
1
+ # -*- coding: utf-8 -*-
2
+ from transit.writer import Writer
3
+ from transit.reader import Reader
4
+ from transit.transit_types import URI
5
+ from StringIO import StringIO
6
+ import sys
7
+
8
+ io = StringIO()
9
+
10
+ x = set()
11
+ print(x)
12
+
13
+ writer = Writer(io, protocol="json")
14
+ writer.write(x)
15
+ reader = Reader(protocol="json")
16
+ print io.getvalue()
17
+ io.seek(0)
18
+ outcome = reader.read(io)
19
+ print(outcome)
scratch/frozendict.py ADDED
@@ -0,0 +1,14 @@
1
+ from transit.writer import Writer
2
+ from transit.reader import Reader
3
+ import StringIO
4
+
5
+ a={"a":1}
6
+ b={"a":1,"b":2}
7
+
8
+ io = StringIO.StringIO()
9
+ w = Writer(io, protocol="msgpack")
10
+
11
+ w.write([a,b])
12
+ r = Reader(protocol="msgpack")
13
+ result = r.read(StringIO.StringIO(io.getvalue()))
14
+ print result
scratch/int_issue.py ADDED
@@ -0,0 +1,10 @@
1
+ from transit.writer import Writer
2
+ from StringIO import StringIO
3
+
4
+ io = StringIO()
5
+
6
+ writer = Writer(io, "json")
7
+ writer.write([2**53+100, 2**63+100])
8
+
9
+ s = io.getvalue()
10
+ print s
scratch/issue.py ADDED
@@ -0,0 +1,44 @@
1
+ from transit.reader import Reader
2
+ from transit.writer import Writer
3
+ from StringIO import StringIO
4
+ import datetime
5
+
6
+
7
+ class DateHandler(object):
8
+ @staticmethod
9
+ def tag(d):
10
+ return 'p'
11
+
12
+ @staticmethod
13
+ def rep(d):
14
+ return str(d)
15
+
16
+ @staticmethod
17
+ def string_rep(d):
18
+ return str(d)
19
+
20
+ @staticmethod
21
+ def from_rep(d):
22
+ return datetime.datetime.strptime(d, '%Y-%m-%d').date()
23
+
24
+
25
+ my_data = {
26
+ 'start_date': datetime.date(2014, 9, 9),
27
+ 'end_date': datetime.date(2014, 10, 10)
28
+ }
29
+
30
+ io = StringIO()
31
+ writer = Writer(io, "json")
32
+ writer.register(datetime.date, DateHandler)
33
+ writer.write(my_data)
34
+ output = io.getvalue()
35
+ io.close()
36
+
37
+
38
+ reader = Reader()
39
+ reader.register('p', DateHandler)
40
+ parsed = reader.read(StringIO(output))
41
+
42
+ assert parsed['start_date'] == my_data['start_date'] # Should be fine
43
+ assert parsed['end_date'] == my_data['end_date'] # Error here - actual value of parsed['end_date'] is (u'start_date', u'2014-10-10')
44
+ print(parsed)
scratch/mp_test.py ADDED
@@ -0,0 +1,22 @@
1
+ import transit.writer as twriter
2
+ import transit.reader as treader
3
+ from io import BytesIO
4
+ from StringIO import StringIO
5
+ from datetime import datetime
6
+ import dateutil.tz
7
+ from uuid import UUID
8
+
9
+ b = BytesIO()
10
+ #b = StringIO()
11
+ r = treader.Reader(protocol="msgpack")
12
+ w = twriter.Writer(b, protocol="msgpack")
13
+
14
+ UUIDS = (UUID('5a2cbea3-e8c6-428b-b525-21239370dd55'),
15
+ UUID('d1dc64fa-da79-444b-9fa4-d4412f427289'),
16
+ UUID('501a978e-3a3e-4060-b3be-1cf2bd4b1a38'),
17
+ UUID('b3ba141a-a776-48e4-9fae-a28ea8571f58'))
18
+
19
+ w.write(UUIDS)
20
+ print(b.getvalue())
21
+ b.seek(0)
22
+ print r.read(b)
@@ -0,0 +1,19 @@
1
+ from transit.reader import Reader
2
+ from transit.writer import Writer
3
+ from StringIO import StringIO
4
+
5
+ #json = "{\"~#set\":[{\"~#set\":[1,3,2]},{\"~#set\":[null,0,2.0,\"~~eight\",1,true,\"five\",false,\"~$seven\",\"~:six\"]}]}\n"
6
+ #mpcode = "94a37e6360a37e637ea37e635ea37e6323".decode("hex")
7
+
8
+ json = "{\"~#set\":[1,true]}"
9
+ io = StringIO()
10
+ io.write(json)
11
+ io.seek(0)
12
+ r = Reader(protocol="json")
13
+ correct = r.read(io)
14
+ out = StringIO()
15
+ w = Writer(out, protocol="json")
16
+ w.write(correct)
17
+ print(json)
18
+ print(out.getvalue())
19
+
scratch/newline.py ADDED
@@ -0,0 +1,14 @@
1
+ from transit.reader import Reader
2
+ from transit.writer import Writer
3
+ from StringIO import StringIO
4
+
5
+ s = 'a\nb'
6
+
7
+ io = StringIO()
8
+ writer = Writer(io, 'json')
9
+ writer.write(s)
10
+ output = io.getvalue()
11
+ io.close()
12
+
13
+ reader = Reader()
14
+ assert s == reader.read(StringIO(output))
scratch/streamit.py ADDED
@@ -0,0 +1,56 @@
1
+ from StringIO import StringIO
2
+ from copy import copy
3
+ import json
4
+
5
+ DELIMS = {"{" : "}",
6
+ "[" : "]",
7
+ "\"": "\""}
8
+
9
+ SKIP = [" ", "\n", "\t"]
10
+
11
+ ESCAPE = "\\"
12
+
13
+ def read_chunk(stream):
14
+ """Ignore whitespace outside of strings.
15
+ """
16
+ chunk = stream.read(1)
17
+ while chunk in SKIP:
18
+ chunk = stream.read(1)
19
+ if chunk == "\"":
20
+ chunk += stream.read(1)
21
+ while not chunk.endswith("\""):
22
+ if chunk[-1] == ESCAPE:
23
+ chunk += stream.read(2)
24
+ else:
25
+ chunk += stream.read(1)
26
+ return chunk
27
+
28
+ def yield_json(stream):
29
+ buff = u""
30
+ arr_count = 0
31
+ obj_count = 0
32
+ while True:
33
+ buff += read_chunk(stream)
34
+
35
+ if buff.endswith('{'):
36
+ obj_count += 1
37
+ if buff.endswith('['):
38
+ arr_count += 1
39
+ if buff.endswith(']'):
40
+ arr_count -= 1
41
+ if obj_count == arr_count == 0:
42
+ json_item = copy(buff)
43
+ buff = u""
44
+ yield json_item
45
+ if buff.endswith('}'):
46
+ obj_count -= 1
47
+ if obj_count == arr_count == 0:
48
+ json_item = copy(buff)
49
+ buff = u""
50
+ yield json_item
51
+
52
+ if __name__ == "__main__":
53
+ x = StringIO("""[\"^ \",\"~:key0000\",0,\"~:key0001\",1,\"~:key0002\",2,\"~:key0003\",3,\"~:key0004\",4,\"~:key0005\",5,\"~:key0006\",6,\"~:key0007\",7,\"~:key0008\",8,\"~:key0009\",9]\n""")
54
+ # x = StringIO("""{\"~#'\":false}\n""")
55
+ for a in yield_json(x):
56
+ print(a)
scratch/testmprt.py ADDED
@@ -0,0 +1,15 @@
1
+ from transit import reader, writer
2
+ from StringIO import StringIO
3
+
4
+ for fmt in ("msgpack", "json"):
5
+ io = StringIO()
6
+ w = writer.Writer(io, fmt)
7
+
8
+ for item in [0, 1, 1902382]:
9
+ w.write(item)
10
+
11
+ io.seek(0)
12
+ r = reader.Reader(fmt, io)
13
+
14
+ for item in r.read():
15
+ print(item)
scratch/unicodeme.py ADDED
@@ -0,0 +1,21 @@
1
+ # -*- coding: utf-8 -*-
2
+ from transit.writer import Writer
3
+ from transit.reader import Reader
4
+ from transit.transit_types import URI
5
+ from StringIO import StringIO
6
+ import sys
7
+
8
+ io = StringIO()
9
+
10
+ x = URI(u'http://www.詹姆斯.com/')
11
+ print(x)
12
+
13
+ writer = Writer(io, protocol="json-verbose")
14
+ writer.write(x)
15
+ reader = Reader(protocol="json-verbose")
16
+ print io.getvalue()
17
+ io.seek(0)
18
+ outcome = reader.read(io)
19
+ print(outcome)
20
+
21
+
tests/exemplars_test.py CHANGED
@@ -14,26 +14,24 @@
14
14
  ## limitations under the License.
15
15
  import unittest
16
16
 
17
- # get parent directory into python path
18
- import sys, os
19
- sys.path.append(os.path.abspath(os.path.dirname(__file__) + os.path.sep + os.path.pardir))
20
-
21
17
  # then import transit stuff
22
18
  from transit.reader import Reader, JsonUnmarshaler, MsgPackUnmarshaler
23
19
  from transit.writer import Writer
24
- from transit.transit_types import Keyword, Symbol, URI, frozendict, TaggedValue, Link
20
+ from transit.transit_types import Keyword, Symbol, URI, frozendict, TaggedValue, Link, true, false
25
21
  from StringIO import StringIO
26
22
  from transit.helpers import mapcat
27
23
  from helpers import ints_centered_on, hash_of_size, array_of_symbools
28
24
  from uuid import UUID
29
25
  from datetime import datetime
30
26
  import dateutil.tz
27
+ from math import isnan
31
28
 
32
29
  class ExemplarBaseTest(unittest.TestCase):
33
30
  pass
34
31
 
35
32
  def exemplar(name, val):
36
33
  class ExemplarTest(ExemplarBaseTest):
34
+
37
35
  def test_json(self):
38
36
  with open("../transit-format/examples/0.8/simple/" + name + ".json", 'r') as stream:
39
37
  data = Reader(protocol="json").read(stream)
@@ -87,13 +85,18 @@ def exemplar(name, val):
87
85
  try:
88
86
  return unittest.TestCase.assertEqual(self, val, data)
89
87
  except AssertionError as e:
90
- e.args += (name, "failed")
91
- raise
88
+ if not False in [isnan(v) and isnan(d) or isnan(v) == isnan(d)
89
+ for v, d in zip (val, data)]:
90
+ return unittest.TestCase.assertEqual(self, filter(lambda x: not isnan(x), val),
91
+ filter(lambda x: not isnan(x), data))
92
+ else:
93
+ e.args += (name, "failed")
94
+ raise
92
95
 
93
96
  globals()["test_" + name + "_json"] = ExemplarTest
94
97
 
95
98
  ARRAY_SIMPLE = (1, 2, 3)
96
- ARRAY_MIXED = (0, 1, 2.0, True, False, 'five', Keyword("six"), Symbol("seven"), '~eight', None)
99
+ ARRAY_MIXED = (0, 1, 2.0, true, false, 'five', Keyword("six"), Symbol("seven"), '~eight', None)
97
100
  ARRAY_NESTED = (ARRAY_SIMPLE, ARRAY_MIXED)
98
101
  SMALL_STRINGS = ("", "a", "ab", "abc", "abcd", "abcde", "abcdef")
99
102
  POWERS_OF_TWO = tuple(map(lambda x: pow(2, x), range(66)))
@@ -128,14 +131,14 @@ MAP_SIMPLE = frozendict({Keyword("a"): 1,
128
131
 
129
132
  MAP_MIXED = frozendict({Keyword("a"): 1,
130
133
  Keyword("b"): u"a string",
131
- Keyword("c"): True})
134
+ Keyword("c"): true})
132
135
 
133
136
  MAP_NESTED = frozendict({Keyword("simple"): MAP_SIMPLE,
134
137
  Keyword("mixed"): MAP_MIXED})
135
138
 
136
139
  exemplar("nil", None)
137
- exemplar("true", True)
138
- exemplar("false", False)
140
+ exemplar("true", true)
141
+ exemplar("false", false)
139
142
  exemplar("zero", 0)
140
143
  exemplar("one", 1)
141
144
  exemplar("one_string", "hello")
@@ -215,6 +218,8 @@ exemplar("maps_four_char_string_keys", ({"aaaa": 1, "bbbb": 2},
215
218
  exemplar("maps_unrecognized_keys", (TaggedValue("abcde", Keyword("anything")),
216
219
  TaggedValue("fghij", Keyword("anything-else")),))
217
220
 
221
+ exemplar("vector_special_numbers", (float("nan"), float("inf"), float("-inf")))
222
+
218
223
  # Doesn't exist in simple examples but gave me tests to verify Link.
219
224
  #exemplar("link", Link("http://www.blah.com", "test", "test", "link", "test"))
220
225
 
tests/regression.py ADDED
@@ -0,0 +1,80 @@
1
+ ## Copyright 2014 Cognitect. All Rights Reserved.
2
+ ##
3
+ ## Licensed under the Apache License, Version 2.0 (the "License");
4
+ ## you may not use this file except in compliance with the License.
5
+ ## You may obtain a copy of the License at
6
+ ##
7
+ ## http://www.apache.org/licenses/LICENSE-2.0
8
+ ##
9
+ ## Unless required by applicable law or agreed to in writing, software
10
+ ## distributed under the License is distributed on an "AS-IS" BASIS,
11
+ ## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ ## See the License for the specific language governing permissions and
13
+ ## limitations under the License.
14
+
15
+ # This test suite verifies that issues corrected remain corrected.
16
+ import unittest
17
+
18
+ from transit.reader import Reader
19
+ from transit.writer import Writer
20
+ from transit.transit_types import Symbol, frozendict, true, false
21
+ from StringIO import StringIO
22
+
23
+ class RegressionBaseTest(unittest.TestCase):
24
+ pass
25
+
26
+ def regression(name, value):
27
+ class RegressionTest(RegressionBaseTest):
28
+
29
+ def test_roundtrip(self):
30
+ in_data = value
31
+ io = StringIO()
32
+ w = Writer(io, "json")
33
+ w.write(in_data)
34
+ r = Reader("json")
35
+ out_data = r.read(StringIO(io.getvalue()))
36
+ self.assertEqual(in_data, out_data)
37
+
38
+ globals()["test_" + name + "_json"] = RegressionTest
39
+
40
+ regression("cache_consistency", ({"Problem?":true},
41
+ Symbol("Here"),
42
+ Symbol("Here")))
43
+ regression("one_pair_frozendict", frozendict({"a":1}))
44
+ regression("json_int_max", (2**53+100, 2**63+100))
45
+ regression("newline_in_string", "a\nb")
46
+
47
+ class BooleanTest(unittest.TestCase):
48
+ """Even though we're roundtripping transit_types.true and
49
+ transit_types.false now, make sure we can still write Python bools.
50
+
51
+ Additionally, make sure we can still do basic logical evaluation on transit
52
+ Boolean values.
53
+ """
54
+ def test_write_bool(self):
55
+ for protocol in ("json", "json-verbose", "msgpack"):
56
+ io = StringIO()
57
+ w = Writer(io, protocol)
58
+ w.write((True, False))
59
+ r = Reader(protocol)
60
+ io.seek(0)
61
+ out_data = r.read(io)
62
+ assert out_data[0] == true
63
+ assert out_data[1] == false
64
+
65
+ def test_basic_eval(self):
66
+ assert true
67
+ assert not false
68
+
69
+ def test_or(self):
70
+ assert true or false
71
+ assert not (false or false)
72
+ assert true or true
73
+
74
+ def test_and(self):
75
+ assert not (true and false)
76
+ assert true and true
77
+ assert not (false and false)
78
+
79
+ if __name__ == '__main__':
80
+ unittest.main()
transit/class_hash.py CHANGED
@@ -16,14 +16,14 @@
16
16
  import collections
17
17
 
18
18
  class ClassDict(collections.MutableMapping):
19
- """ A dictionary that looks up class/type keys with inheritance"""
19
+ """A dictionary that looks up class/type keys with inheritance."""
20
20
 
21
21
  def __init__(self, *args, **kwargs):
22
22
  self.store = dict()
23
23
  self.update(dict(*args, **kwargs))
24
24
 
25
25
  def __getitem__(self, key):
26
- key = isinstance(key, type) and key or type(key)
26
+ key = key if isinstance(key, type) else type(key)
27
27
  if key in self.store:
28
28
  return self.store[key]
29
29
  else:
transit/decoder.py CHANGED
@@ -18,6 +18,7 @@ from collections import OrderedDict
18
18
  from helpers import pairs
19
19
  import read_handlers as rh
20
20
  from rolling_cache import RollingCache, is_cacheable, is_cache_key
21
+ from transit_types import true, false
21
22
 
22
23
  class Tag(object):
23
24
  def __init__(self, tag):
@@ -34,6 +35,7 @@ default_options = {"decoders": {"_": rh.NoneHandler,
34
35
  "t": rh.DateHandler,
35
36
  "m": rh.DateHandler,
36
37
  "n": rh.BigIntegerHandler,
38
+ "z": rh.SpecialNumbersHandler,
37
39
  "link": rh.LinkHandler,
38
40
  "list": rh.ListHandler,
39
41
  "set": rh.SetHandler,
@@ -47,7 +49,7 @@ ground_decoders = {"_": rh.NoneHandler,
47
49
  "'": rh.IdentityHandler}
48
50
 
49
51
  class Decoder(object):
50
- """ The Decoder is the lowest level entry point for parsing, decoding, and
52
+ """The Decoder is the lowest level entry point for parsing, decoding, and
51
53
  fully converting Transit data into Python objects.
52
54
 
53
55
  During the creation of a Decoder object, you can specify custom options
@@ -55,7 +57,8 @@ class Decoder(object):
55
57
  can specify your own decoders and override many of the built in decoders,
56
58
  some decoders are silently enforced and cannot be overriden. These are
57
59
  known as Ground Decoders, and are needed to maintain bottom-tier
58
- compatibility."""
60
+ compatibility.
61
+ """
59
62
 
60
63
  def __init__(self, options={}):
61
64
  self.options = default_options.copy()
@@ -66,11 +69,12 @@ class Decoder(object):
66
69
  self.decoders.update(ground_decoders)
67
70
 
68
71
  def decode(self, node, cache=None, as_map_key=False):
69
- """ Given a node of data (any supported decodeable obj - string, dict,
72
+ """Given a node of data (any supported decodeable obj - string, dict,
70
73
  list), return the decoded object. Optionally set the current decode
71
74
  cache [None]. If None, a new RollingCache is instantiated and used.
72
75
  You may also hit to the decoder that this node is to be treated as a
73
- map key [False]. This is used internally."""
76
+ map key [False]. This is used internally.
77
+ """
74
78
  if not cache:
75
79
  cache = RollingCache()
76
80
  return self._decode(node, cache, as_map_key)
@@ -85,18 +89,19 @@ class Decoder(object):
85
89
  return self.decode_list(node, cache, as_map_key)
86
90
  elif tp is str:
87
91
  return self.decode_string(unicode(node, "utf-8"), cache, as_map_key)
88
- else:
89
- return node
92
+ elif tp is bool:
93
+ return true if node else false
94
+ return node
90
95
 
91
96
  def decode_list(self, node, cache, as_map_key):
92
- """ Special case decodes map-as-array.
97
+ """Special case decodes map-as-array.
93
98
  Otherwise lists are treated as Python lists.
94
99
 
95
100
  Arguments follow the same convention as the top-level 'decode'
96
- function"""
101
+ function.
102
+ """
97
103
  if node:
98
- decoded = self._decode(node[0], cache, as_map_key)
99
- if decoded == MAP_AS_ARR:
104
+ if node[0] == MAP_AS_ARR:
100
105
  # key must be decoded before value for caching to work.
101
106
  returned_dict = {}
102
107
  for k,v in pairs(node[1:]):
@@ -104,16 +109,16 @@ class Decoder(object):
104
109
  val = self._decode(v, cache, as_map_key)
105
110
  returned_dict[key] = val
106
111
  return returned_dict
107
- # return {self._decode(k, cache, True):
108
- # self._decode(v, cache, as_map_key)
109
- # for k,v in pairs(node[1:])}
110
- elif isinstance(decoded, Tag):
112
+
113
+ decoded = self._decode(node[0], cache, as_map_key)
114
+ if isinstance(decoded, Tag):
111
115
  return self.decode_tag(decoded.tag, self._decode(node[1], cache, as_map_key))
112
116
  return tuple(self._decode(x, cache, as_map_key) for x in node)
113
117
 
114
118
  def decode_string(self, string, cache, as_map_key):
115
- """ Decode a string - arguments follow the same convention as the
116
- top-level 'decode' function"""
119
+ """Decode a string - arguments follow the same convention as the
120
+ top-level 'decode' function.
121
+ """
117
122
  if is_cache_key(string):
118
123
  return self.parse_string(cache.decode(string, as_map_key), cache, as_map_key)
119
124
  if is_cacheable(string, as_map_key):
@@ -131,7 +136,14 @@ class Decoder(object):
131
136
  if len(hash) != 1:
132
137
  h = {}
133
138
  for k, v in hash.items():
134
- h[self._decode(k, cache, True)] = self._decode(v, cache, False)
139
+ # crude/verbose implementation, but this is only version that
140
+ # plays nice w/cache for both msgpack and json thus far.
141
+ # -- e.g., we have to specify encode/decode order for key/val
142
+ # -- explicitly, all implicit ordering has broken in corner
143
+ # -- cases, thus these extraneous seeming assignments
144
+ key = self._decode(k, cache, True)
145
+ val = self._decode(v, cache, False)
146
+ h[key] = val
135
147
  return transit_types.frozendict(h)
136
148
  else:
137
149
  key,value = hash.items()[0]
@@ -139,7 +151,7 @@ class Decoder(object):
139
151
  if isinstance(key, Tag):
140
152
  return self.decode_tag(key.tag, self._decode(value, cache, as_map_key))
141
153
  else:
142
- return {key: self._decode(value, cache, False)}
154
+ return transit_types.frozendict({key: self._decode(value, cache, False)})
143
155
 
144
156
  def parse_string(self, string, cache, as_map_key):
145
157
  if string.startswith(ESC):
@@ -155,10 +167,11 @@ class Decoder(object):
155
167
  return string
156
168
 
157
169
  def register(self, key_or_tag, obj):
158
- """ Register a custom Transit tag and new parsing function with the
170
+ """Register a custom Transit tag and new parsing function with the
159
171
  decoder. Also, you can optionally set the 'default_decoder' with
160
172
  this function. Your new tag and parse/decode function will be added
161
- to the interal dictionary of decoders for this Decoder object"""
173
+ to the interal dictionary of decoders for this Decoder object.
174
+ """
162
175
  if key_or_tag == "default_decoder":
163
176
  self.options["default_decoder"] = obj
164
177
  else:
transit/read_handlers.py CHANGED
@@ -47,7 +47,7 @@ class SymbolHandler(object):
47
47
  class BooleanHandler(object):
48
48
  @staticmethod
49
49
  def from_rep(x):
50
- return x == "t"
50
+ return transit_types.true if x == "t" else transit_types.false
51
51
 
52
52
  class IntHandler(object):
53
53
  @staticmethod
@@ -62,7 +62,7 @@ class FloatHandler(object):
62
62
  class UuidHandler(object):
63
63
  @staticmethod
64
64
  def from_rep(u):
65
- """ Given a string, return a UUID object"""
65
+ """Given a string, return a UUID object."""
66
66
  if isinstance(u, basestring):
67
67
  return uuid.UUID(u)
68
68
 
@@ -87,7 +87,7 @@ class DateHandler(object):
87
87
  return DateHandler._convert_timestamp(long(d))
88
88
  @staticmethod
89
89
  def _convert_timestamp(ms):
90
- """ Given a timestamp in ms, return a DateTime object"""
90
+ """Given a timestamp in ms, return a DateTime object."""
91
91
  return datetime.datetime.fromtimestamp(ms/1000.0, dateutil.tz.tzutc())
92
92
 
93
93
  class BigIntegerHandler(object):
@@ -120,3 +120,13 @@ class IdentityHandler(object):
120
120
  def from_rep(i):
121
121
  return i
122
122
 
123
+ class SpecialNumbersHandler(object):
124
+ @staticmethod
125
+ def from_rep(z):
126
+ if z == 'NaN':
127
+ return float('Nan')
128
+ if z == 'INF':
129
+ return float('Inf')
130
+ if z == '-INF':
131
+ return float('-Inf')
132
+ raise ValueError("Don't know how to handle: " + str(z) + " as \"z\"")