gremlinpython 3.6.8__py3-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.
Files changed (37) hide show
  1. gremlin_python/__init__.py +20 -0
  2. gremlin_python/__version__.py +20 -0
  3. gremlin_python/driver/__init__.py +20 -0
  4. gremlin_python/driver/aiohttp/__init__.py +18 -0
  5. gremlin_python/driver/aiohttp/transport.py +242 -0
  6. gremlin_python/driver/client.py +206 -0
  7. gremlin_python/driver/connection.py +106 -0
  8. gremlin_python/driver/driver_remote_connection.py +183 -0
  9. gremlin_python/driver/protocol.py +259 -0
  10. gremlin_python/driver/remote_connection.py +84 -0
  11. gremlin_python/driver/request.py +25 -0
  12. gremlin_python/driver/resultset.py +100 -0
  13. gremlin_python/driver/serializer.py +294 -0
  14. gremlin_python/driver/transport.py +45 -0
  15. gremlin_python/driver/useragent.py +37 -0
  16. gremlin_python/process/__init__.py +20 -0
  17. gremlin_python/process/anonymous_traversal.py +64 -0
  18. gremlin_python/process/graph_traversal.py +2301 -0
  19. gremlin_python/process/strategies.py +239 -0
  20. gremlin_python/process/translator.py +297 -0
  21. gremlin_python/process/traversal.py +875 -0
  22. gremlin_python/statics.py +117 -0
  23. gremlin_python/structure/__init__.py +20 -0
  24. gremlin_python/structure/graph.py +134 -0
  25. gremlin_python/structure/io/__init__.py +20 -0
  26. gremlin_python/structure/io/graphbinaryV1.py +1153 -0
  27. gremlin_python/structure/io/graphsonV2d0.py +646 -0
  28. gremlin_python/structure/io/graphsonV3d0.py +766 -0
  29. gremlin_python/structure/io/util.py +60 -0
  30. gremlinpython-3.6.8.data/data/LICENSE +202 -0
  31. gremlinpython-3.6.8.data/data/NOTICE +5 -0
  32. gremlinpython-3.6.8.dist-info/LICENSE +202 -0
  33. gremlinpython-3.6.8.dist-info/METADATA +147 -0
  34. gremlinpython-3.6.8.dist-info/NOTICE +5 -0
  35. gremlinpython-3.6.8.dist-info/RECORD +37 -0
  36. gremlinpython-3.6.8.dist-info/WHEEL +5 -0
  37. gremlinpython-3.6.8.dist-info/top_level.txt +1 -0
@@ -0,0 +1,646 @@
1
+ #
2
+ # Licensed to the Apache Software Foundation (ASF) under one
3
+ # or more contributor license agreements. See the NOTICE file
4
+ # distributed with this work for additional information
5
+ # regarding copyright ownership. The ASF licenses this file
6
+ # to you under the Apache License, Version 2.0 (the
7
+ # "License"); you may not use this file except in compliance
8
+ # with the License. You may obtain a copy of the License at
9
+ #
10
+ # http://www.apache.org/licenses/LICENSE-2.0
11
+ #
12
+ # Unless required by applicable law or agreed to in writing,
13
+ # software distributed under the License is distributed on an
14
+ # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15
+ # KIND, either express or implied. See the License for the
16
+ # specific language governing permissions and limitations
17
+ # under the License.
18
+ #
19
+
20
+ import calendar
21
+ import datetime
22
+ import json
23
+ import uuid
24
+ import math
25
+ from collections import OrderedDict
26
+ from decimal import *
27
+ from datetime import timedelta
28
+
29
+ from aenum import Enum
30
+ from isodate import parse_duration, duration_isoformat
31
+
32
+ from gremlin_python import statics
33
+ from gremlin_python.statics import FloatType, FunctionType, ShortType, IntType, LongType, TypeType, SingleByte, ByteBufferType, SingleChar
34
+ from gremlin_python.process.traversal import Binding, Bytecode, P, TextP, Traversal, Traverser, TraversalStrategy
35
+ from gremlin_python.structure.graph import Edge, Property, Vertex, VertexProperty, Path
36
+ from gremlin_python.structure.io.util import SymbolUtil
37
+
38
+ # When we fall back to a superclass's serializer, we iterate over this map.
39
+ # We want that iteration order to be consistent, so we use an OrderedDict,
40
+ # not a dict.
41
+ _serializers = OrderedDict()
42
+ _deserializers = {}
43
+
44
+
45
+ class GraphSONTypeType(type):
46
+ def __new__(mcs, name, bases, dct):
47
+ cls = super(GraphSONTypeType, mcs).__new__(mcs, name, bases, dct)
48
+ if not name.startswith('_'):
49
+ if cls.python_type:
50
+ _serializers[cls.python_type] = cls
51
+ if cls.graphson_type:
52
+ _deserializers[cls.graphson_type] = cls
53
+ return cls
54
+
55
+
56
+ class GraphSONUtil(object):
57
+ TYPE_KEY = "@type"
58
+ VALUE_KEY = "@value"
59
+
60
+ @classmethod
61
+ def typed_value(cls, type_name, value, prefix="g"):
62
+ out = {cls.TYPE_KEY: cls.format_type(prefix, type_name)}
63
+ if value is not None:
64
+ out[cls.VALUE_KEY] = value
65
+ return out
66
+
67
+ @classmethod
68
+ def format_type(cls, prefix, type_name):
69
+ return "%s:%s" % (prefix, type_name)
70
+
71
+
72
+ # Read/Write classes split to follow precedence of the Java API
73
+ class GraphSONWriter(object):
74
+ def __init__(self, serializer_map=None):
75
+ """
76
+ :param serializer_map: map from Python type to serializer instance implementing `dictify`
77
+ """
78
+ self.serializers = _serializers.copy()
79
+ if serializer_map:
80
+ self.serializers.update(serializer_map)
81
+
82
+ def write_object(self, objectData):
83
+ # to JSON
84
+ return json.dumps(self.to_dict(objectData), separators=(',', ':'))
85
+
86
+ def to_dict(self, obj):
87
+ """
88
+ Encodes python objects in GraphSON type-tagged dict values
89
+ """
90
+ try:
91
+ return self.serializers[type(obj)].dictify(obj, self)
92
+ except KeyError:
93
+ for key, serializer in self.serializers.items():
94
+ if isinstance(obj, key):
95
+ return serializer.dictify(obj, self)
96
+
97
+ # list and map are treated as normal json objs (could be isolated serializers)
98
+ if isinstance(obj, (list, set)):
99
+ return [self.to_dict(o) for o in obj]
100
+ elif isinstance(obj, dict):
101
+ return dict((self.to_dict(k), self.to_dict(v)) for k, v in obj.items())
102
+ else:
103
+ return obj
104
+
105
+
106
+ class GraphSONReader(object):
107
+ def __init__(self, deserializer_map=None):
108
+ """
109
+ :param deserializer_map: map from GraphSON type tag to deserializer instance implementing `objectify`
110
+ """
111
+ self.deserializers = _deserializers.copy()
112
+ if deserializer_map:
113
+ self.deserializers.update(deserializer_map)
114
+
115
+ def read_object(self, json_data):
116
+ # from JSON
117
+ return self.to_object(json.loads(json_data))
118
+
119
+ def to_object(self, obj):
120
+ """
121
+ Unpacks GraphSON type-tagged dict values into objects mapped in self.deserializers
122
+ """
123
+ if isinstance(obj, dict):
124
+ try:
125
+ return self.deserializers[obj[GraphSONUtil.TYPE_KEY]].objectify(obj[GraphSONUtil.VALUE_KEY], self)
126
+ except KeyError:
127
+ pass
128
+ # list and map are treated as normal json objs (could be isolated deserializers)
129
+ return dict((self.to_object(k), self.to_object(v)) for k, v in obj.items())
130
+ elif isinstance(obj, list):
131
+ return [self.to_object(o) for o in obj]
132
+ else:
133
+ return obj
134
+
135
+
136
+ class _GraphSONTypeIO(object, metaclass=GraphSONTypeType):
137
+ python_type = None
138
+ graphson_type = None
139
+
140
+ def dictify(self, obj, writer):
141
+ raise NotImplementedError()
142
+
143
+ def objectify(self, d, reader):
144
+ raise NotImplementedError()
145
+
146
+
147
+ class _BytecodeSerializer(_GraphSONTypeIO):
148
+ @classmethod
149
+ def _dictify_instructions(cls, instructions, writer):
150
+ out = []
151
+ for instruction in instructions:
152
+ inst = [instruction[0]]
153
+ inst.extend(writer.to_dict(arg) for arg in instruction[1:])
154
+ out.append(inst)
155
+ return out
156
+
157
+ @classmethod
158
+ def dictify(cls, bytecode, writer):
159
+ if isinstance(bytecode, Traversal):
160
+ bytecode = bytecode.bytecode
161
+ out = {}
162
+ if bytecode.source_instructions:
163
+ out["source"] = cls._dictify_instructions(bytecode.source_instructions, writer)
164
+ if bytecode.step_instructions:
165
+ out["step"] = cls._dictify_instructions(bytecode.step_instructions, writer)
166
+ return GraphSONUtil.typed_value("Bytecode", out)
167
+
168
+ class TraversalSerializer(_BytecodeSerializer):
169
+ python_type = Traversal
170
+
171
+
172
+ class BytecodeSerializer(_BytecodeSerializer):
173
+ python_type = Bytecode
174
+
175
+
176
+ class VertexSerializer(_GraphSONTypeIO):
177
+ python_type = Vertex
178
+ graphson_type = "g:Vertex"
179
+
180
+ @classmethod
181
+ def dictify(cls, vertex, writer):
182
+ return GraphSONUtil.typed_value("Vertex", {"id": writer.to_dict(vertex.id),
183
+ "label": writer.to_dict(vertex.label)})
184
+
185
+
186
+ class EdgeSerializer(_GraphSONTypeIO):
187
+ python_type = Edge
188
+ graphson_type = "g:Edge"
189
+
190
+ @classmethod
191
+ def dictify(cls, edge, writer):
192
+ return GraphSONUtil.typed_value("Edge", {"id": writer.to_dict(edge.id),
193
+ "outV": writer.to_dict(edge.outV.id),
194
+ "outVLabel": writer.to_dict(edge.outV.label),
195
+ "label": writer.to_dict(edge.label),
196
+ "inV": writer.to_dict(edge.inV.id),
197
+ "inVLabel": writer.to_dict(edge.inV.label)})
198
+
199
+
200
+ class VertexPropertySerializer(_GraphSONTypeIO):
201
+ python_type = VertexProperty
202
+ graphson_type = "g:VertexProperty"
203
+
204
+ @classmethod
205
+ def dictify(cls, vertex_property, writer):
206
+ return GraphSONUtil.typed_value("VertexProperty", {"id": writer.to_dict(vertex_property.id),
207
+ "label": writer.to_dict(vertex_property.label),
208
+ "value": writer.to_dict(vertex_property.value),
209
+ "vertex": writer.to_dict(vertex_property.vertex.id)})
210
+
211
+
212
+ class PropertySerializer(_GraphSONTypeIO):
213
+ python_type = Property
214
+ graphson_type = "g:Property"
215
+
216
+ @classmethod
217
+ def dictify(cls, property, writer):
218
+ element_dict = writer.to_dict(property.element)
219
+ if element_dict is not None:
220
+ value_dict = element_dict["@value"]
221
+ if "outVLabel" in value_dict:
222
+ del value_dict["outVLabel"]
223
+ if "inVLabel" in value_dict:
224
+ del value_dict["inVLabel"]
225
+ if "properties" in value_dict:
226
+ del value_dict["properties"]
227
+ if "value" in value_dict:
228
+ del value_dict["value"]
229
+ return GraphSONUtil.typed_value("Property", {"key": writer.to_dict(property.key),
230
+ "value": writer.to_dict(property.value),
231
+ "element": element_dict})
232
+
233
+
234
+ class TraversalStrategySerializer(_GraphSONTypeIO):
235
+ python_type = TraversalStrategy
236
+
237
+ @classmethod
238
+ def dictify(cls, strategy, writer):
239
+ return GraphSONUtil.typed_value(strategy.strategy_name, writer.to_dict(strategy.configuration))
240
+
241
+
242
+ class TraverserIO(_GraphSONTypeIO):
243
+ python_type = Traverser
244
+ graphson_type = "g:Traverser"
245
+
246
+ @classmethod
247
+ def dictify(cls, traverser, writer):
248
+ return GraphSONUtil.typed_value("Traverser", {"value": writer.to_dict(traverser.object),
249
+ "bulk": writer.to_dict(traverser.bulk)})
250
+
251
+ @classmethod
252
+ def objectify(cls, d, reader):
253
+ return Traverser(reader.to_object(d["value"]),
254
+ reader.to_object(d["bulk"]))
255
+
256
+
257
+ class EnumSerializer(_GraphSONTypeIO):
258
+ python_type = Enum
259
+
260
+ @classmethod
261
+ def dictify(cls, enum, _):
262
+ return GraphSONUtil.typed_value(SymbolUtil.to_camel_case(type(enum).__name__),
263
+ SymbolUtil.to_camel_case(str(enum.name)))
264
+
265
+
266
+ class PSerializer(_GraphSONTypeIO):
267
+ python_type = P
268
+
269
+ @classmethod
270
+ def dictify(cls, p, writer):
271
+ out = {"predicate": p.operator,
272
+ "value": [writer.to_dict(p.value), writer.to_dict(p.other)] if p.other is not None else
273
+ writer.to_dict(p.value)}
274
+ return GraphSONUtil.typed_value("P", out)
275
+
276
+
277
+ class TextPSerializer(_GraphSONTypeIO):
278
+ python_type = TextP
279
+
280
+ @classmethod
281
+ def dictify(cls, p, writer):
282
+ out = {"predicate": p.operator,
283
+ "value": [writer.to_dict(p.value), writer.to_dict(p.other)] if p.other is not None else
284
+ writer.to_dict(p.value)}
285
+ return GraphSONUtil.typed_value("TextP", out)
286
+
287
+
288
+ class BindingSerializer(_GraphSONTypeIO):
289
+ python_type = Binding
290
+
291
+ @classmethod
292
+ def dictify(cls, binding, writer):
293
+ out = {"key": binding.key,
294
+ "value": writer.to_dict(binding.value)}
295
+ return GraphSONUtil.typed_value("Binding", out)
296
+
297
+
298
+ class LambdaSerializer(_GraphSONTypeIO):
299
+ python_type = FunctionType
300
+
301
+ @classmethod
302
+ def dictify(cls, lambda_object, writer):
303
+ lambda_result = lambda_object()
304
+ script = lambda_result if isinstance(lambda_result, str) else lambda_result[0]
305
+ language = statics.default_lambda_language if isinstance(lambda_result, str) else lambda_result[1]
306
+ out = {"script": script,
307
+ "language": language}
308
+ if language == "gremlin-groovy" and "->" in script:
309
+ # if the user has explicitly added parameters to the groovy closure then we can easily detect one or two
310
+ # arg lambdas - if we can't detect 1 or 2 then we just go with "unknown"
311
+ args = script[0:script.find("->")]
312
+ out["arguments"] = 2 if "," in args else 1
313
+ else:
314
+ out["arguments"] = -1
315
+
316
+ return GraphSONUtil.typed_value("Lambda", out)
317
+
318
+
319
+ class TypeSerializer(_GraphSONTypeIO):
320
+ python_type = TypeType
321
+
322
+ @classmethod
323
+ def dictify(cls, typ, writer):
324
+ return writer.to_dict(typ())
325
+
326
+
327
+ class UUIDIO(_GraphSONTypeIO):
328
+ python_type = uuid.UUID
329
+ graphson_type = "g:UUID"
330
+ graphson_base_type = "UUID"
331
+
332
+ @classmethod
333
+ def dictify(cls, obj, writer):
334
+ return GraphSONUtil.typed_value(cls.graphson_base_type, str(obj))
335
+
336
+ @classmethod
337
+ def objectify(cls, d, reader):
338
+ return cls.python_type(d)
339
+
340
+
341
+ class DateIO(_GraphSONTypeIO):
342
+ python_type = datetime.datetime
343
+ graphson_type = "g:Date"
344
+ graphson_base_type = "Date"
345
+
346
+ @classmethod
347
+ def dictify(cls, obj, writer):
348
+ try:
349
+ timestamp_seconds = calendar.timegm(obj.utctimetuple())
350
+ pts = timestamp_seconds * 1e3 + getattr(obj, 'microsecond', 0) / 1e3
351
+ except AttributeError:
352
+ pts = calendar.timegm(obj.timetuple()) * 1e3
353
+
354
+ ts = int(round(pts))
355
+ return GraphSONUtil.typed_value(cls.graphson_base_type, ts)
356
+
357
+ @classmethod
358
+ def objectify(cls, ts, reader):
359
+ # Python timestamp expects seconds
360
+ return datetime.datetime.utcfromtimestamp(ts / 1000.0)
361
+
362
+
363
+ # Based on current implementation, this class must always be declared before FloatIO.
364
+ # Seems pretty fragile for future maintainers. Maybe look into this.
365
+ class TimestampIO(_GraphSONTypeIO):
366
+ """A timestamp in Python is type float"""
367
+ python_type = statics.timestamp
368
+ graphson_type = "g:Timestamp"
369
+ graphson_base_type = "Timestamp"
370
+
371
+ @classmethod
372
+ def dictify(cls, obj, writer):
373
+ # Java timestamp expects milliseconds integer
374
+ # Have to use int because of legacy Python
375
+ ts = int(round(obj * 1000))
376
+ return GraphSONUtil.typed_value(cls.graphson_base_type, ts)
377
+
378
+ @classmethod
379
+ def objectify(cls, ts, reader):
380
+ # Python timestamp expects seconds
381
+ return cls.python_type(ts / 1000.0)
382
+
383
+
384
+ class _NumberIO(_GraphSONTypeIO):
385
+ @classmethod
386
+ def dictify(cls, n, writer):
387
+ if isinstance(n, bool): # because isinstance(False, int) and isinstance(True, int)
388
+ return n
389
+ return GraphSONUtil.typed_value(cls.graphson_base_type, n)
390
+
391
+ @classmethod
392
+ def objectify(cls, v, _):
393
+ return cls.python_type(v)
394
+
395
+
396
+ class FloatIO(_NumberIO):
397
+ python_type = FloatType
398
+ graphson_type = "g:Float"
399
+ graphson_base_type = "Float"
400
+
401
+ @classmethod
402
+ def dictify(cls, n, writer):
403
+ if isinstance(n, bool): # because isinstance(False, int) and isinstance(True, int)
404
+ return n
405
+ elif math.isnan(n):
406
+ return GraphSONUtil.typed_value(cls.graphson_base_type, "NaN")
407
+ elif math.isinf(n) and n > 0:
408
+ return GraphSONUtil.typed_value(cls.graphson_base_type, "Infinity")
409
+ elif math.isinf(n) and n < 0:
410
+ return GraphSONUtil.typed_value(cls.graphson_base_type, "-Infinity")
411
+ else:
412
+ return GraphSONUtil.typed_value(cls.graphson_base_type, n)
413
+
414
+ @classmethod
415
+ def objectify(cls, v, _):
416
+ if isinstance(v, str):
417
+ if v == 'NaN':
418
+ return float('nan')
419
+ elif v == "Infinity":
420
+ return float('inf')
421
+ elif v == "-Infinity":
422
+ return float('-inf')
423
+
424
+ return cls.python_type(v)
425
+
426
+
427
+ class BigDecimalIO(_NumberIO):
428
+ python_type = Decimal
429
+ graphson_type = "gx:BigDecimal"
430
+ graphson_base_type = "BigDecimal"
431
+
432
+ @classmethod
433
+ def dictify(cls, n, writer):
434
+ if isinstance(n, bool): # because isinstance(False, int) and isinstance(True, int)
435
+ return n
436
+ elif math.isnan(n):
437
+ return GraphSONUtil.typed_value(cls.graphson_base_type, "NaN", "gx")
438
+ elif math.isinf(n) and n > 0:
439
+ return GraphSONUtil.typed_value(cls.graphson_base_type, "Infinity", "gx")
440
+ elif math.isinf(n) and n < 0:
441
+ return GraphSONUtil.typed_value(cls.graphson_base_type, "-Infinity", "gx")
442
+ else:
443
+ return GraphSONUtil.typed_value(cls.graphson_base_type, str(n), "gx")
444
+
445
+ @classmethod
446
+ def objectify(cls, v, _):
447
+ if isinstance(v, str):
448
+ if v == 'NaN':
449
+ return Decimal('nan')
450
+ elif v == "Infinity":
451
+ return Decimal('inf')
452
+ elif v == "-Infinity":
453
+ return Decimal('-inf')
454
+
455
+ return Decimal(v)
456
+
457
+
458
+ class DoubleIO(FloatIO):
459
+ graphson_type = "g:Double"
460
+ graphson_base_type = "Double"
461
+
462
+
463
+ class Int64IO(_NumberIO):
464
+ python_type = LongType
465
+ graphson_type = "g:Int64"
466
+ graphson_base_type = "Int64"
467
+
468
+ @classmethod
469
+ def dictify(cls, n, writer):
470
+ # if we exceed Java long range then we need a BigInteger
471
+ if isinstance(n, bool):
472
+ return n
473
+ elif n < -9223372036854775808 or n > 9223372036854775807:
474
+ return GraphSONUtil.typed_value("BigInteger", str(n), "gx")
475
+ else:
476
+ return GraphSONUtil.typed_value(cls.graphson_base_type, n)
477
+
478
+
479
+ class BigIntegerIO(Int64IO):
480
+ graphson_type = "gx:BigInteger"
481
+
482
+
483
+ class Int32IO(Int64IO):
484
+ python_type = IntType
485
+ graphson_type = "g:Int32"
486
+ graphson_base_type = "Int32"
487
+
488
+ @classmethod
489
+ def dictify(cls, n, writer):
490
+ # if we exceed Java int range then we need a long
491
+ if isinstance(n, bool):
492
+ return n
493
+ elif n < -9223372036854775808 or n > 9223372036854775807:
494
+ return GraphSONUtil.typed_value("BigInteger", str(n), "gx")
495
+ elif n < -2147483648 or n > 2147483647:
496
+ return GraphSONUtil.typed_value("Int64", n)
497
+ else:
498
+ return GraphSONUtil.typed_value(cls.graphson_base_type, n)
499
+
500
+
501
+ class Int16IO(Int64IO):
502
+ python_type = ShortType
503
+ graphson_type = "gx:Int16"
504
+ graphson_base_type = "Int16"
505
+
506
+ @classmethod
507
+ def dictify(cls, n, writer):
508
+ # if we exceed Java int range then we need a long
509
+ if isinstance(n, bool):
510
+ return n
511
+ elif n < -9223372036854775808 or n > 9223372036854775807:
512
+ return GraphSONUtil.typed_value("BigInteger", str(n), "gx")
513
+ elif n < -2147483648 or n > 2147483647:
514
+ return GraphSONUtil.typed_value("Int64", n)
515
+ elif n < -32768 or n > 32767:
516
+ return GraphSONUtil.typed_value("Int32", n)
517
+ else:
518
+ return GraphSONUtil.typed_value(cls.graphson_base_type, n, "gx")
519
+
520
+ @classmethod
521
+ def objectify(cls, v, _):
522
+ return int.__new__(ShortType, v)
523
+
524
+
525
+ class ByteIO(_NumberIO):
526
+ python_type = SingleByte
527
+ graphson_type = "gx:Byte"
528
+ graphson_base_type = "Byte"
529
+
530
+ @classmethod
531
+ def dictify(cls, n, writer):
532
+ if isinstance(n, bool): # because isinstance(False, int) and isinstance(True, int)
533
+ return n
534
+ return GraphSONUtil.typed_value(cls.graphson_base_type, n, "gx")
535
+
536
+ @classmethod
537
+ def objectify(cls, v, _):
538
+ return int.__new__(SingleByte, v)
539
+
540
+
541
+ class ByteBufferIO(_GraphSONTypeIO):
542
+ python_type = ByteBufferType
543
+ graphson_type = "gx:ByteBuffer"
544
+ graphson_base_type = "ByteBuffer"
545
+
546
+ @classmethod
547
+ def dictify(cls, n, writer):
548
+ return GraphSONUtil.typed_value(cls.graphson_base_type, "".join(chr(x) for x in n), "gx")
549
+
550
+ @classmethod
551
+ def objectify(cls, v, _):
552
+ return cls.python_type(v, "utf8")
553
+
554
+
555
+ class CharIO(_GraphSONTypeIO):
556
+ python_type = SingleChar
557
+ graphson_type = "gx:Char"
558
+ graphson_base_type = "Char"
559
+
560
+ @classmethod
561
+ def dictify(cls, n, writer):
562
+ return GraphSONUtil.typed_value(cls.graphson_base_type, n, "gx")
563
+
564
+ @classmethod
565
+ def objectify(cls, v, _):
566
+ return str.__new__(SingleChar, v)
567
+
568
+
569
+ class DurationIO(_GraphSONTypeIO):
570
+ python_type = timedelta
571
+ graphson_type = "gx:Duration"
572
+ graphson_base_type = "Duration"
573
+
574
+ @classmethod
575
+ def dictify(cls, n, writer):
576
+ return GraphSONUtil.typed_value(cls.graphson_base_type, duration_isoformat(n), "gx")
577
+
578
+ @classmethod
579
+ def objectify(cls, v, _):
580
+ return parse_duration(v)
581
+
582
+
583
+ class VertexDeserializer(_GraphSONTypeIO):
584
+ graphson_type = "g:Vertex"
585
+
586
+ @classmethod
587
+ def objectify(cls, d, reader):
588
+ return Vertex(reader.to_object(d["id"]), d.get("label", "vertex"))
589
+
590
+
591
+ class EdgeDeserializer(_GraphSONTypeIO):
592
+ graphson_type = "g:Edge"
593
+
594
+ @classmethod
595
+ def objectify(cls, d, reader):
596
+ return Edge(reader.to_object(d["id"]),
597
+ Vertex(reader.to_object(d["outV"]), d.get("outVLabel", "vertex")),
598
+ d.get("label", "edge"),
599
+ Vertex(reader.to_object(d["inV"]), d.get("inVLabel", "vertex")))
600
+
601
+
602
+ class VertexPropertyDeserializer(_GraphSONTypeIO):
603
+ graphson_type = "g:VertexProperty"
604
+
605
+ @classmethod
606
+ def objectify(cls, d, reader):
607
+ vertex = Vertex(reader.to_object(d.get("vertex"))) if "vertex" in d else None
608
+ return VertexProperty(reader.to_object(d["id"]),
609
+ d["label"],
610
+ reader.to_object(d["value"]),
611
+ vertex)
612
+
613
+
614
+ class PropertyDeserializer(_GraphSONTypeIO):
615
+ graphson_type = "g:Property"
616
+
617
+ @classmethod
618
+ def objectify(cls, d, reader):
619
+ element = reader.to_object(d["element"]) if "element" in d else None
620
+ return Property(d["key"], reader.to_object(d["value"]), element)
621
+
622
+
623
+ class PathDeserializer(_GraphSONTypeIO):
624
+ graphson_type = "g:Path"
625
+
626
+ @classmethod
627
+ def objectify(cls, d, reader):
628
+ labels = [set(label) for label in d["labels"]]
629
+ objects = [reader.to_object(o) for o in d["objects"]]
630
+ return Path(labels, objects)
631
+
632
+
633
+ class TraversalMetricsDeserializer(_GraphSONTypeIO):
634
+ graphson_type = "g:TraversalMetrics"
635
+
636
+ @classmethod
637
+ def objectify(cls, d, reader):
638
+ return reader.to_object(d)
639
+
640
+
641
+ class MetricsDeserializer(_GraphSONTypeIO):
642
+ graphson_type = "g:Metrics"
643
+
644
+ @classmethod
645
+ def objectify(cls, d, reader):
646
+ return reader.to_object(d)