transit-python 0.8.174-__py2.7.egg → 0.8.240__py2.7.egg
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.
- EGG-INFO/PKG-INFO +1 -1
- EGG-INFO/SOURCES.txt +16 -1
- EGG-INFO/requires.txt +1 -1
- EGG-INFO/top_level.txt +1 -0
- scratch/__init__.py +1 -0
- scratch/__init__.pyc +0 -0
- scratch/bools.py +15 -0
- scratch/bools.pyc +0 -0
- scratch/cache-inconsistent.py +10 -0
- scratch/cache-inconsistent.pyc +0 -0
- scratch/dt.py +7 -0
- scratch/dt.pyc +0 -0
- scratch/emptyset.py +19 -0
- scratch/emptyset.pyc +0 -0
- scratch/frozendict.py +14 -0
- scratch/frozendict.pyc +0 -0
- scratch/int_issue.py +10 -0
- scratch/int_issue.pyc +0 -0
- scratch/issue.py +44 -0
- scratch/issue.pyc +0 -0
- scratch/mp_test.py +22 -0
- scratch/mp_test.pyc +0 -0
- scratch/msgpack_issue.py +19 -0
- scratch/msgpack_issue.pyc +0 -0
- scratch/newline.py +14 -0
- scratch/newline.pyc +0 -0
- scratch/streamit.py +56 -0
- scratch/streamit.pyc +0 -0
- scratch/testmprt.py +15 -0
- scratch/testmprt.pyc +0 -0
- scratch/unicodeme.py +21 -0
- scratch/unicodeme.pyc +0 -0
- tests/__init__.pyc +0 -0
- tests/exemplars_test.py +16 -11
- tests/exemplars_test.pyc +0 -0
- tests/helpers.pyc +0 -0
- tests/regression.py +80 -0
- tests/regression.pyc +0 -0
- tests/seattle_benchmark.pyc +0 -0
- transit/__init__.pyc +0 -0
- transit/class_hash.py +2 -2
- transit/class_hash.pyc +0 -0
- transit/constants.pyc +0 -0
- transit/decoder.py +33 -20
- transit/decoder.pyc +0 -0
- transit/helpers.pyc +0 -0
- transit/read_handlers.py +13 -3
- transit/read_handlers.pyc +0 -0
- transit/reader.py +34 -10
- transit/reader.pyc +0 -0
- transit/rolling_cache.py +3 -6
- transit/rolling_cache.pyc +0 -0
- transit/sosjson.py +74 -0
- transit/sosjson.pyc +0 -0
- transit/transit_types.py +33 -7
- transit/transit_types.pyc +0 -0
- transit/write_handlers.py +18 -11
- transit/write_handlers.pyc +0 -0
- transit/writer.py +83 -60
- transit/writer.pyc +0 -0
- tests/transit_types_test.py +0 -24
- tests/transit_types_test.pyc +0 -0
- /EGG-INFO/{not-zip-safe → zip-safe} +0 -0
transit/writer.py
CHANGED
|
@@ -19,13 +19,16 @@ from write_handlers import WriteHandler
|
|
|
19
19
|
from transit_types import TaggedValue
|
|
20
20
|
import re
|
|
21
21
|
|
|
22
|
+
JSON_ESCAPED_CHARS = set([unichr(c) for c in range(0x20)] + ["\\", "\n"])
|
|
23
|
+
|
|
22
24
|
class Writer(object):
|
|
23
|
-
"""
|
|
25
|
+
"""The top-level object for writing out Python objects and converting them
|
|
24
26
|
to Transit data. During initialization, you must specify the protocol used
|
|
25
27
|
for marshalling the data- json or msgpack. You must also specify the io
|
|
26
28
|
source used for writing (a file descriptor). You may optionally pass in
|
|
27
29
|
an options dictionary that will be forwarded onto the Marshaler.
|
|
28
|
-
The cache is enabled by default.
|
|
30
|
+
The cache is enabled by default.
|
|
31
|
+
"""
|
|
29
32
|
def __init__(self, io, protocol="json", opts={"cache_enabled": True}):
|
|
30
33
|
if protocol == "json":
|
|
31
34
|
self.marshaler = JsonMarshaler(io, opts=opts)
|
|
@@ -35,19 +38,22 @@ class Writer(object):
|
|
|
35
38
|
self.marshaler = MsgPackMarshaler(io, opts=opts)
|
|
36
39
|
|
|
37
40
|
def write(self, obj):
|
|
38
|
-
"""
|
|
39
|
-
the 'io' source.
|
|
41
|
+
"""Given a Python object, marshal it into Transit data and write it to
|
|
42
|
+
the 'io' source.
|
|
43
|
+
"""
|
|
40
44
|
self.marshaler.marshal_top(obj)
|
|
41
45
|
|
|
42
46
|
def register(self, obj_type, handler_class):
|
|
43
|
-
"""
|
|
47
|
+
"""Register custom converters for object types present in your
|
|
44
48
|
application. This allows you to extend Transit to encode new types.
|
|
45
49
|
You must specify the obj type to be encoded, and the handler class
|
|
46
|
-
that should be used by the Marshaler during write-time.
|
|
50
|
+
that should be used by the Marshaler during write-time.
|
|
51
|
+
"""
|
|
47
52
|
self.marshaler.register(obj_type, handler_class)
|
|
48
53
|
|
|
49
54
|
def flatten_map(m):
|
|
50
|
-
"""
|
|
55
|
+
"""Expand a dictionary's items into a flat list
|
|
56
|
+
"""
|
|
51
57
|
# This is the fastest way to do this in Python
|
|
52
58
|
return [item for t in m.items() for item in t]
|
|
53
59
|
|
|
@@ -61,17 +67,20 @@ def re_fn(pat):
|
|
|
61
67
|
is_escapable = re_fn("^" + re.escape(SUB) + "|" + ESC + "|" + RES)
|
|
62
68
|
|
|
63
69
|
def escape(s):
|
|
70
|
+
if s is MAP_AS_ARR:
|
|
71
|
+
return MAP_AS_ARR
|
|
64
72
|
if is_escapable(s):
|
|
65
73
|
return ESC+s
|
|
66
74
|
else:
|
|
67
75
|
return s
|
|
68
76
|
|
|
69
77
|
class Marshaler(object):
|
|
70
|
-
"""
|
|
78
|
+
"""The base Marshaler from which all Marshalers inherit.
|
|
71
79
|
|
|
72
80
|
The Marshaler specifies how to emit Transit data given encodeable Python
|
|
73
81
|
objects. The end of this process is specialized by other Marshalers to
|
|
74
|
-
covert the final result into an on-the-wire payload (JSON or MsgPack).
|
|
82
|
+
covert the final result into an on-the-wire payload (JSON or MsgPack).
|
|
83
|
+
"""
|
|
75
84
|
def __init__(self, opts = {}):
|
|
76
85
|
self.opts = opts
|
|
77
86
|
self._init_handlers()
|
|
@@ -80,8 +89,9 @@ class Marshaler(object):
|
|
|
80
89
|
self.handlers = WriteHandler()
|
|
81
90
|
|
|
82
91
|
def are_stringable_keys(self, m):
|
|
83
|
-
"""
|
|
84
|
-
that can be optimized and whose keys can be cached
|
|
92
|
+
"""Test whether the keys within a map are stringable - a simple map,
|
|
93
|
+
that can be optimized and whose keys can be cached
|
|
94
|
+
"""
|
|
85
95
|
for x in m.keys():
|
|
86
96
|
if len(self.handlers[x].tag(x)) != 1:
|
|
87
97
|
return False
|
|
@@ -91,7 +101,7 @@ class Marshaler(object):
|
|
|
91
101
|
return self.emit_string(ESC, "_", None, True, cache) if as_map_key else self.emit_object(None)
|
|
92
102
|
|
|
93
103
|
def emit_string(self, prefix, tag, string, as_map_key, cache):
|
|
94
|
-
encoded = cache.encode(str(prefix)+tag+
|
|
104
|
+
encoded = cache.encode(str(prefix)+tag+string, as_map_key)
|
|
95
105
|
# TODO: Remove this optimization for the time being - it breaks the cache
|
|
96
106
|
#if "cache_enabled" in self.opts and is_cacheable(encoded, as_map_key):
|
|
97
107
|
# return self.emit_object(cache.value_to_key[encoded], as_map_key)
|
|
@@ -100,9 +110,9 @@ class Marshaler(object):
|
|
|
100
110
|
def emit_boolean(self, b, as_map_key, cache):
|
|
101
111
|
return self.emit_string(ESC, "?", b, True, cache) if as_map_key else self.emit_object(b)
|
|
102
112
|
|
|
103
|
-
def emit_int(self, i, as_map_key, cache):
|
|
113
|
+
def emit_int(self, tag, i, as_map_key, cache):
|
|
104
114
|
if as_map_key or i > self.opts["max_int"] or i < self.opts["min_int"]:
|
|
105
|
-
return self.emit_string(ESC,
|
|
115
|
+
return self.emit_string(ESC, tag, str(i), as_map_key, cache)
|
|
106
116
|
else:
|
|
107
117
|
return self.emit_object(i, as_map_key)
|
|
108
118
|
|
|
@@ -127,9 +137,9 @@ class Marshaler(object):
|
|
|
127
137
|
self.marshal(flatten_map(m), False, cache)
|
|
128
138
|
self.emit_map_end()
|
|
129
139
|
|
|
130
|
-
def emit_tagged(self, tag, rep,
|
|
140
|
+
def emit_tagged(self, tag, rep, cache):
|
|
131
141
|
self.emit_array_start(2)
|
|
132
|
-
self.
|
|
142
|
+
self.emit_string(ESC, "#", tag, False, cache)
|
|
133
143
|
self.marshal(rep, False, cache)
|
|
134
144
|
self.emit_array_end()
|
|
135
145
|
|
|
@@ -147,20 +157,21 @@ class Marshaler(object):
|
|
|
147
157
|
"rep": rep,
|
|
148
158
|
"obj": obj}))
|
|
149
159
|
else:
|
|
150
|
-
self.emit_tagged(tag, rep,
|
|
160
|
+
self.emit_tagged(tag, rep, cache)
|
|
151
161
|
elif as_map_key:
|
|
152
162
|
raise AssertionError("Cannot be used as a map key: " + str({"tag": tag,
|
|
153
163
|
"rep": rep,
|
|
154
164
|
"obj": obj}))
|
|
155
165
|
else:
|
|
156
|
-
self.emit_tagged(tag, rep,
|
|
166
|
+
self.emit_tagged(tag, rep, cache)
|
|
157
167
|
|
|
158
168
|
def marshal(self, obj, as_map_key, cache):
|
|
159
|
-
"""
|
|
169
|
+
"""Marshal an individual obj, potentially as part of another container
|
|
160
170
|
object (like a list/dictionary/etc). Specify if this object is a key
|
|
161
171
|
to a map/dict, and pass in the current cache being used.
|
|
162
172
|
This method should only be called by a top-level marshalling call
|
|
163
|
-
and should not be considered an entry-point for integration.
|
|
173
|
+
and should not be considered an entry-point for integration.
|
|
174
|
+
"""
|
|
164
175
|
handler = self.handlers[obj]
|
|
165
176
|
tag = handler.tag(obj)
|
|
166
177
|
rep = handler.string_rep(obj) if as_map_key else handler.rep(obj)
|
|
@@ -172,9 +183,10 @@ class Marshaler(object):
|
|
|
172
183
|
self.emit_encoded(tag, handler, obj, as_map_key, cache)
|
|
173
184
|
|
|
174
185
|
def marshal_top(self, obj, cache=None):
|
|
175
|
-
"""
|
|
186
|
+
"""Given a complete object that needs to be marshaled into Transit
|
|
176
187
|
data, and optionally a cache, dispatch accordingly, and flush the data
|
|
177
|
-
directly into the IO stream.
|
|
188
|
+
directly into the IO stream.
|
|
189
|
+
"""
|
|
178
190
|
if not cache:
|
|
179
191
|
cache = RollingCache()
|
|
180
192
|
|
|
@@ -192,33 +204,37 @@ class Marshaler(object):
|
|
|
192
204
|
|
|
193
205
|
|
|
194
206
|
def dispatch_map(self, rep, as_map_key, cache):
|
|
195
|
-
"""
|
|
207
|
+
"""Used to determine and dipatch the writing of a map - a simple
|
|
196
208
|
map with strings as keys, or a complex map, whose keys are also
|
|
197
|
-
compound types.
|
|
209
|
+
compound types.
|
|
210
|
+
"""
|
|
198
211
|
if self.are_stringable_keys(rep):
|
|
199
212
|
return self.emit_map(rep, as_map_key, cache)
|
|
200
213
|
return self.emit_cmap(rep, as_map_key, cache)
|
|
201
214
|
|
|
202
215
|
def register(self, obj_type, handler_class):
|
|
203
|
-
"""
|
|
216
|
+
"""Register custom converters for object types present in your
|
|
204
217
|
application. This allows you to extend Transit to encode new types.
|
|
205
218
|
You must specify the obj type to be encoded, and the handler class
|
|
206
|
-
that should be used by this marshaller.
|
|
219
|
+
that should be used by this marshaller.
|
|
220
|
+
"""
|
|
207
221
|
self.handlers[obj_type] = handler_class
|
|
208
222
|
|
|
209
223
|
marshal_dispatch = {"_": Marshaler.emit_nil,
|
|
210
224
|
"?": Marshaler.emit_boolean,
|
|
211
|
-
"s": lambda self, rep, as_map_key, cache: Marshaler.emit_string(self, "", "", rep, as_map_key, cache),
|
|
212
|
-
"i": Marshaler.emit_int,
|
|
225
|
+
"s": lambda self, rep, as_map_key, cache: Marshaler.emit_string(self, "", "", escape(rep), as_map_key, cache),
|
|
226
|
+
"i": lambda self, rep, as_map_key, cache: Marshaler.emit_int(self, "i", rep, as_map_key, cache),
|
|
227
|
+
"n": lambda self, rep, as_map_key, cache: Marshaler.emit_int(self, "n", rep, as_map_key, cache),
|
|
213
228
|
"d": Marshaler.emit_double,
|
|
214
|
-
"'": lambda self, rep, _, cache: Marshaler.emit_tagged(self, "'", rep,
|
|
229
|
+
"'": lambda self, rep, _, cache: Marshaler.emit_tagged(self, "'", rep, cache),
|
|
215
230
|
"array": Marshaler.emit_array,
|
|
216
231
|
"map": Marshaler.dispatch_map}
|
|
217
232
|
|
|
218
233
|
|
|
219
234
|
class MsgPackMarshaler(Marshaler):
|
|
220
|
-
"""
|
|
221
|
-
'msgpack' protocol when creating a Writer.
|
|
235
|
+
"""The Marshaler tailor to MsgPack. To use this Marshaler, specify the
|
|
236
|
+
'msgpack' protocol when creating a Writer.
|
|
237
|
+
"""
|
|
222
238
|
MSGPACK_MAX_INT = pow(2, 63) - 1
|
|
223
239
|
MSGPACK_MIN_INT = -pow(2, 63)
|
|
224
240
|
|
|
@@ -257,20 +273,17 @@ class MsgPackMarshaler(Marshaler):
|
|
|
257
273
|
REPLACE_RE = re.compile("\"")
|
|
258
274
|
|
|
259
275
|
class JsonMarshaler(Marshaler):
|
|
260
|
-
"""
|
|
261
|
-
'json' protocol when creating a Writer.
|
|
262
|
-
|
|
263
|
-
|
|
276
|
+
"""The Marshaler tailor to JSON. To use this Marshaler, specify the
|
|
277
|
+
'json' protocol when creating a Writer.
|
|
278
|
+
"""
|
|
279
|
+
JSON_MAX_INT = pow(2, 53)
|
|
280
|
+
JSON_MIN_INT = -pow(2, 53)
|
|
264
281
|
|
|
265
282
|
default_opts = {"prefer_strings": True,
|
|
266
283
|
"max_int": JSON_MAX_INT,
|
|
267
284
|
"min_int": JSON_MIN_INT}
|
|
268
285
|
|
|
269
|
-
##
|
|
270
|
-
## but I couldn't find an existing solution that worked
|
|
271
|
-
## well with the lazy writing method we have in this
|
|
272
|
-
## project.
|
|
273
|
-
|
|
286
|
+
## Custom JSON encoder temporary solution to support lazy writing.
|
|
274
287
|
def __init__(self, io, opts={}):
|
|
275
288
|
self.io = io
|
|
276
289
|
nopts = JsonMarshaler.default_opts.copy()
|
|
@@ -298,57 +311,67 @@ class JsonMarshaler(Marshaler):
|
|
|
298
311
|
else:
|
|
299
312
|
last = self.is_key[-1]
|
|
300
313
|
if last:
|
|
301
|
-
self.io.write(":")
|
|
314
|
+
self.io.write(u":")
|
|
302
315
|
self.is_key[-1] = False
|
|
303
316
|
elif last is False:
|
|
304
|
-
self.io.write(",")
|
|
317
|
+
self.io.write(u",")
|
|
305
318
|
self.is_key[-1] = True
|
|
306
319
|
else:
|
|
307
320
|
#elif last is None:
|
|
308
|
-
self.io.write(",")
|
|
321
|
+
self.io.write(u",")
|
|
309
322
|
|
|
310
323
|
def emit_array_start(self, size):
|
|
311
324
|
self.write_sep()
|
|
312
|
-
self.io.write("[")
|
|
325
|
+
self.io.write(u"[")
|
|
313
326
|
self.push_level()
|
|
314
327
|
|
|
315
328
|
def emit_array_end(self):
|
|
316
329
|
self.pop_level()
|
|
317
|
-
self.io.write("]")
|
|
330
|
+
self.io.write(u"]")
|
|
318
331
|
|
|
319
332
|
def emit_map(self, m, _, cache):
|
|
320
|
-
"""
|
|
321
|
-
self.
|
|
333
|
+
"""Emits array as per default JSON spec."""
|
|
334
|
+
self.emit_array_start(None)
|
|
335
|
+
self.marshal(MAP_AS_ARR, False, cache)
|
|
336
|
+
for k, v in m.items():
|
|
337
|
+
self.marshal(k, True, cache)
|
|
338
|
+
self.marshal(v, False, cache)
|
|
339
|
+
self.emit_array_end()
|
|
322
340
|
|
|
323
341
|
def emit_map_start(self, size):
|
|
324
342
|
self.write_sep()
|
|
325
|
-
self.io.write("{")
|
|
343
|
+
self.io.write(u"{")
|
|
326
344
|
self.push_map()
|
|
327
345
|
|
|
328
346
|
def emit_map_end(self):
|
|
329
347
|
self.pop_level()
|
|
330
|
-
self.io.write("}")
|
|
348
|
+
self.io.write(u"}")
|
|
331
349
|
|
|
332
350
|
def emit_object(self, obj, as_map_key=False):
|
|
333
351
|
tp = type(obj)
|
|
334
352
|
self.write_sep()
|
|
335
353
|
if tp is str or tp is unicode:
|
|
336
|
-
self.io.write("\"")
|
|
337
|
-
|
|
338
|
-
|
|
354
|
+
self.io.write(u"\"")
|
|
355
|
+
|
|
356
|
+
# escapes in-line for perf
|
|
357
|
+
self.io.write(u"".join([(c.encode("unicode_escape"))
|
|
358
|
+
if c in JSON_ESCAPED_CHARS
|
|
359
|
+
else c for c in obj]).replace("\"", "\\\""))
|
|
360
|
+
self.io.write(u"\"")
|
|
339
361
|
elif tp is int or tp is long or tp is float:
|
|
340
362
|
self.io.write(str(obj))
|
|
341
363
|
elif tp is bool:
|
|
342
|
-
self.io.write("true" if obj else "false")
|
|
364
|
+
self.io.write(u"true" if obj else u"false")
|
|
343
365
|
elif obj is None:
|
|
344
|
-
self.io.write("null")
|
|
366
|
+
self.io.write(u"null")
|
|
345
367
|
else:
|
|
346
368
|
raise AssertionError("Don't know how to encode: " + str(obj))
|
|
347
369
|
|
|
348
370
|
|
|
349
371
|
class VerboseSettings(object):
|
|
350
|
-
"""
|
|
351
|
-
Verbosity is only suggest for debuging/inspecting purposes.
|
|
372
|
+
"""Mixin for JsonMarshaler that adds support for Verbose output/input.
|
|
373
|
+
Verbosity is only suggest for debuging/inspecting purposes.
|
|
374
|
+
"""
|
|
352
375
|
@staticmethod
|
|
353
376
|
def _verbose_handlers(handlers):
|
|
354
377
|
for k, v in handlers.iteritems():
|
|
@@ -360,7 +383,7 @@ class VerboseSettings(object):
|
|
|
360
383
|
self.handlers = self._verbose_handlers(WriteHandler())
|
|
361
384
|
|
|
362
385
|
def emit_string(self, prefix, tag, string, as_map_key, cache):
|
|
363
|
-
return self.emit_object(
|
|
386
|
+
return self.emit_object(unicode(prefix) + tag + string, as_map_key)
|
|
364
387
|
|
|
365
388
|
def emit_map(self, m, _, cache):
|
|
366
389
|
self.emit_map_start(len(m))
|
|
@@ -369,14 +392,14 @@ class VerboseSettings(object):
|
|
|
369
392
|
self.marshal(v, False, cache)
|
|
370
393
|
self.emit_map_end()
|
|
371
394
|
|
|
372
|
-
def emit_tagged(self, tag, rep,
|
|
395
|
+
def emit_tagged(self, tag, rep, cache):
|
|
373
396
|
self.emit_map_start(1)
|
|
374
|
-
self.emit_object(
|
|
397
|
+
self.emit_object(ESC + "#" + tag, True)
|
|
375
398
|
self.marshal(rep, False, cache)
|
|
376
399
|
self.emit_map_end()
|
|
377
400
|
|
|
378
401
|
|
|
379
402
|
class VerboseJsonMarshaler(VerboseSettings, JsonMarshaler):
|
|
380
|
-
"""
|
|
403
|
+
"""JsonMarshaler class with VerboseSettings mixin."""
|
|
381
404
|
pass # All from inheritance and mixin
|
|
382
405
|
|
transit/writer.pyc
CHANGED
|
Binary file
|
tests/transit_types_test.py
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
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
|
-
import unittest
|
|
16
|
-
from transit.transit_types import Keyword
|
|
17
|
-
|
|
18
|
-
class KeyWordTest(unittest.TestCase):
|
|
19
|
-
def test_equality(self):
|
|
20
|
-
self.assertEqual(Keyword("foo"), Keyword("foo"))
|
|
21
|
-
self.assertNotEqual(Keyword("foo"), Keyword("bar"))
|
|
22
|
-
self.assertEqual(Keyword(u"foo"), Keyword("foo"))
|
|
23
|
-
|
|
24
|
-
self.assertEqual((Keyword("foo"), Keyword("bar")), (Keyword("foo"), Keyword("bar")))
|
tests/transit_types_test.pyc
DELETED
|
Binary file
|
|
File without changes
|