You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by xi...@apache.org on 2023/10/18 07:51:40 UTC

[tinkerpop] branch add-http-gremlin-python updated (033453d6af -> 0bf9fec0a5)

This is an automated email from the ASF dual-hosted git repository.

xiazcy pushed a change to branch add-http-gremlin-python
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


    omit 033453d6af fix python translator & add additional types
    omit 931bdd6168 update str translation to use repr()
    omit ce29c41390 nit remove un-needed comments
     new 0bf9fec0a5 fix python translator & add additional types

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (033453d6af)
            \
             N -- N -- N   refs/heads/add-http-gremlin-python (0bf9fec0a5)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../src/main/python/gremlin_python/process/translator.py    | 13 -------------
 1 file changed, 13 deletions(-)


[tinkerpop] 01/01: fix python translator & add additional types

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiazcy pushed a commit to branch add-http-gremlin-python
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 0bf9fec0a5f31699a4535149c61c314ff6dfb910
Author: Yang Xia <55...@users.noreply.github.com>
AuthorDate: Wed Oct 18 00:51:31 2023 -0700

    fix python translator & add additional types
---
 .../traversal/translator/GroovyTranslator.java     |   2 +-
 .../traversal/translator/GroovyTranslatorTest.java |  15 ++
 .../gremlin_python/driver/aiohttp/transport.py     |   3 -
 .../main/python/gremlin_python/driver/client.py    |   1 -
 .../python/gremlin_python/process/translator.py    | 110 +++++++-
 .../driver/test_driver_remote_connection_http.py   |  26 +-
 .../main/python/tests/process/test_translator.py   | 276 ++++++++++++---------
 7 files changed, 293 insertions(+), 140 deletions(-)

diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GroovyTranslator.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GroovyTranslator.java
index 7fea7eb829..d87c841514 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GroovyTranslator.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GroovyTranslator.java
@@ -186,7 +186,7 @@ public final class GroovyTranslator implements Translator.ScriptTranslator {
                 if (NumberHelper.isPositiveInfinity(o))
                     return (o instanceof Double ? "Double" : "Float") + ".POSITIVE_INFINITY";
                 if (NumberHelper.isNegativeInfinity(o))
-                    return (o instanceof Double ? "Double" : "Float") + ".POSITIVE_INFINITY";
+                    return (o instanceof Double ? "Double" : "Float") + ".NEGATIVE_INFINITY";
 
                 return o + (o instanceof Double ? "d" : "f");
             }
diff --git a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GroovyTranslatorTest.java b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GroovyTranslatorTest.java
index b9910fbbc8..082c6cf353 100644
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GroovyTranslatorTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/GroovyTranslatorTest.java
@@ -212,6 +212,21 @@ public class GroovyTranslatorTest {
         assertTranslation("Scope.local", Scope.local);
     }
 
+    @Test
+    public void shouldTranslateNaN() {
+        assertTranslation("Double.NaN", Double.NaN);
+    }
+
+    @Test
+    public void shouldTranslatePosInf() {
+        assertTranslation("Double.POSITIVE_INFINITY", Double.POSITIVE_INFINITY);
+    }
+
+    @Test
+    public void shouldTranslateNegInf() {
+        assertTranslation("Double.NEGATIVE_INFINITY", Double.NEGATIVE_INFINITY);
+    }
+
     @Test
     public void shouldIncludeCustomTypeTranslationForSomethingSilly() throws Exception {
         final SillyClass notSillyEnough = SillyClass.from("not silly enough", 100);
diff --git a/gremlin-python/src/main/python/gremlin_python/driver/aiohttp/transport.py b/gremlin-python/src/main/python/gremlin_python/driver/aiohttp/transport.py
index 4b9ead23cc..c5facb9120 100644
--- a/gremlin-python/src/main/python/gremlin_python/driver/aiohttp/transport.py
+++ b/gremlin-python/src/main/python/gremlin_python/driver/aiohttp/transport.py
@@ -169,9 +169,6 @@ class AiohttpHTTPTransport(AbstractBaseTransport):
             self._ssl_context = self._aiohttp_kwargs.pop("ssl_options")
             self._enable_ssl = True
 
-        # if "ssl_options" in self._aiohttp_kwargs:
-        #     self._aiohttp_kwargs["ssl_context"] = self._aiohttp_kwargs.pop("ssl_options")
-
     def __del__(self):
         # Close will only actually close if things are left open, so this is safe to call.
         # Clean up any connection resources and close the event loop.
diff --git a/gremlin-python/src/main/python/gremlin_python/driver/client.py b/gremlin-python/src/main/python/gremlin_python/driver/client.py
index 6ad9fd5517..74d90a32d0 100644
--- a/gremlin-python/src/main/python/gremlin_python/driver/client.py
+++ b/gremlin-python/src/main/python/gremlin_python/driver/client.py
@@ -59,7 +59,6 @@ class Client:
             transport_kwargs["max_content_length"] = 10 * 1024 * 1024
         if message_serializer is None:
             message_serializer = serializer.GraphBinarySerializersV1()
-            # message_serializer = serializer.GraphSONMessageSerializer()
 
         self._message_serializer = message_serializer
         self._username = username
diff --git a/gremlin-python/src/main/python/gremlin_python/process/translator.py b/gremlin-python/src/main/python/gremlin_python/process/translator.py
index 9f29e44eb3..e3e04d34fa 100755
--- a/gremlin-python/src/main/python/gremlin_python/process/translator.py
+++ b/gremlin-python/src/main/python/gremlin_python/process/translator.py
@@ -24,6 +24,8 @@ sent to any TinkerPop compliant HTTP endpoint.
 """
 __author__ = 'Kelvin R. Lawrence (gfxman)'
 
+import math
+import numbers
 import re
 
 from gremlin_python.process.traversal import *
@@ -51,6 +53,8 @@ class Translator:
         WithOptions.map: 'map'
     }
 
+    conn_p = ['and', 'or']
+
     def __init__(self, traversal_source=None):
         self.traversal_source = traversal_source
 
@@ -68,11 +72,26 @@ class Translator:
     # of strings and dates and boolean.
     def fixup(self, v):
         if isinstance(v, str):
-            return f'\'{v}\''
+            return f'{v!r}'  # use repr() format for canonical string rep
         elif type(v) == datetime:
             return self.process_date(v)
         elif type(v) == bool:
             return 'true' if v else 'false'
+        elif isinstance(v, numbers.Number):
+            return self.process_number(v)
+        elif isinstance(v, set):
+            return f'[{str(v)[1:-1]}]'
+        elif isinstance(v, P):
+            return self.process_predicate(v)
+        elif type(v) == Vertex:
+            return self.process_vertex(v)
+        elif type(v) == Edge:
+            return self.process_edge(v)
+        elif type(v) in [Merge]:  # on_create on_match out_v in_v
+            tmp = str(v)
+            return f'{tmp.split("_")[0]}{tmp.split("_")[1].capitalize()}' if tmp.find('_') else tmp
+        elif v is None:
+            return 'null'
         else:
             return str(v)
 
@@ -89,17 +108,35 @@ class Translator:
     # Do special processing needed to format predicates that come in
     # such as "gt(a)" correctly.
     def process_predicate(self, p):
-        res = str(p).split('(')[0] + '('
+        res = ''
+        if p.operator in self.conn_p:
+            res += f'{self.process_predicate(p.value)}.{p.operator}({self.process_predicate(p.other)})'
+        else:
+            res += f'{self.process_p_value(p)}'
+        return res
 
+    # adds all the nested connective predicates in order in a list
+    def process_conn_p(self, p, p_list=None):
+        if p.operator in self.conn_p:
+            self.process_conn_p(p.value, p_list)
+            p_list.append(p.operator)
+            self.process_conn_p(p.other, p_list)
+        else:
+            p_list.append(self.process_p_value(p))
+        return p_list
+
+    # process the value of the predicates
+    def process_p_value(self, p):
+        res = str(p).split('(')[0] + '('
         if type(p.value) == list:
             res += '['
             for v in p.value:
                 res += self.fixup(v) + ','
-            res = res[0:-1] + ']'
+            res = (res[0:-1] + ']') if len(p.value) > 0 else (res + ']')
         else:
             res += self.fixup(p.value)
             if p.other is not None:
-                res += ',' + self.fixup(p.other)
+                res += f',{self.fixup(p.other)}'
         res += ')'
         return res
 
@@ -109,7 +146,7 @@ class Translator:
         res = ''
         # if parameter is empty, only pass class name (referenced GroovyTranslator.java)
         if not s.configuration:
-            res += s.__class__.__name__
+            res += s.strategy_name
         else:
             res = f'new {str(s)}('
             for key in s.configuration:
@@ -127,7 +164,7 @@ class Translator:
 
     # Special processing to handle vertices
     def process_vertex(self, vertex):
-        return f'new ReferenceVertex({str(vertex.id)},\'{vertex.label}\')'
+        return f'new ReferenceVertex({self.fixup(vertex.id)},\'{vertex.label}\')'
 
     # Special processing to handle edges
     def process_edge(self, edge):
@@ -143,7 +180,47 @@ class Translator:
     def process_lambda(self, lam):
         lambda_result = lam()
         script = lambda_result if isinstance(lambda_result, str) else lambda_result[0]
-        return f'{script}' if re.match(r"^\{.*\}$", script) else f'{{{script}}}'
+        return f'{script}' if re.match(r"^\{.*\}$", script, flags=re.DOTALL) else f'{{{script}}}'
+
+    def process_dict(self, d):
+        c = 0
+        res = '['
+        if len(d) == 0:
+            res += ':'
+        else:
+            for k, v in d.items():
+                wrap = not isinstance(k, str)
+                res += ',' if c > 0 else ''
+                res += '(' if wrap else ''
+                res += self.fixup(k)
+                res += ')' if wrap else ''
+                res += f':{self.fixup(v)}'
+                c += 1
+        res += ']'
+        return res
+
+    def process_number(self, n):
+        if isinstance(n, float):
+            # converting floats into doubles for script since python doesn't distinguish and java defaults to double
+            if math.isnan(n):
+                return "Double.NaN"
+            elif math.isinf(n) and n > 0:
+                return "Double.POSITIVE_INFINITY"
+            elif math.isinf(n) and n < 0:
+                return "Double.NEGATIVE_INFINITY"
+            else:
+                return f'{n}d'
+        return f'{n}'
+
+    def process_list(self, l):
+        c = 0
+        res = '['
+        for i in l:
+            res += ',' if c > 0 else ''
+            res += self.fixup(i)
+            c += 1
+        res += ']'
+        return res
 
     # Special processing to handle bindings inside of traversals
     def process_binding(self, binding):
@@ -158,6 +235,7 @@ class Translator:
         if len(params) > 0:
             c = 0
             with_opts = False
+            is_merge_op = (step[0] == 'mergeV') or (step[0] == 'mergeE')
             for p in params:
                 script += ',' if c > 0 else ''
                 if with_opts:
@@ -172,9 +250,13 @@ class Translator:
                     script += self.process_edge(p)
                 elif type(p) == VertexProperty:
                     script += self.process_vertex_property(p)
-                elif type(p) in [Cardinality, Pop, Operator]:
+                elif type(p) in [Cardinality, Pop, Operator, Scope, T]:
                     tmp = str(p)
                     script += tmp[0:-1] if tmp.endswith('_') else tmp
+                elif type(p) in [Merge]:  # on_create on_match out_v in_v
+                    is_merge_op = True
+                    tmp = str(p)
+                    script += f'{tmp.split("_")[0]}{tmp.split("_")[1].capitalize()}' if tmp.find('_') else tmp
                 elif isinstance(p, TraversalStrategy):  # this will capture all strategies
                     script += self.process_strategy(p)
                 elif type(p) == datetime:
@@ -183,7 +265,7 @@ class Translator:
                     script += 'WithOptions.tokens'
                     with_opts = True
                 elif isinstance(p, str):
-                    script += f'\'{p}\''
+                    script += f'{p!r}'  # use repr() format for canonical string rep
                 elif type(p) == bool:
                     script += 'true' if p else 'false'
                 elif isinstance(p, type(lambda: None)) and p.__name__ == (lambda: None).__name__:
@@ -191,9 +273,17 @@ class Translator:
                 elif type(p) == Binding:
                     script += self.process_binding(p)
                 elif p is None:
-                    script += 'null'
+                    script += '(Traversal) null' if is_merge_op else 'null'
                 elif isinstance(p, type):
                     script += p.__name__
+                elif isinstance(p, dict):
+                    script += self.process_dict(p)
+                elif isinstance(p, numbers.Number):
+                    script += self.process_number(p)
+                elif isinstance(p, set):
+                    script += f'[{str(p)[1:-1]}] as Set' if len(p) > 0 else '[] as Set'
+                elif isinstance(p, list):
+                    script += self.process_list(p)
                 else:
                     script += str(p)
                 c += 1
diff --git a/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection_http.py b/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection_http.py
index 765dcd7e30..af8f636b27 100644
--- a/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection_http.py
+++ b/gremlin-python/src/main/python/tests/driver/test_driver_remote_connection_http.py
@@ -19,7 +19,6 @@
 import os
 
 from gremlin_python import statics
-from gremlin_python.driver.protocol import GremlinServerError
 from gremlin_python.statics import long
 from gremlin_python.process.traversal import Traverser
 from gremlin_python.process.traversal import TraversalStrategy
@@ -28,14 +27,24 @@ from gremlin_python.process.traversal import P, Order, T
 from gremlin_python.process.graph_traversal import __
 from gremlin_python.process.anonymous_traversal import traversal
 from gremlin_python.structure.graph import Vertex
-from gremlin_python.process.strategies import SubgraphStrategy, ReservedKeysVerificationStrategy, SeedStrategy
+from gremlin_python.process.strategies import SubgraphStrategy, SeedStrategy
 from gremlin_python.structure.io.util import HashableDict
 from gremlin_python.driver.serializer import GraphSONSerializersV2d0
 
 gremlin_server_url_http = os.environ.get('GREMLIN_SERVER_URL_HTTP', 'http://localhost:{}/')
 test_no_auth_http_url = gremlin_server_url_http.format(45940)
 
-# due to the limitation of relying on python translator for sending scripts over HTTP, certain tests are omitted
+"""
+Due to the limitation of relying on python translator for sending groovy scripts over HTTP, certain tests are omitted.
+
+Some known limitation with current HTTP via groovy script translator:
+- Any known limitation with groovy script will be inherited, such as injection of 2 items with the second null, 
+    e.g. g.inject(null, null), will lead to NPE
+- Any server side NPE will cause hanging with no response, need to check server HTTP handlers
+- HTTPS only works with HttpChannelizer, need to check how WsAndHttpChannelizer handles SSL
+- No transaction support
+"""
+
 class TestDriverRemoteConnectionHttp(object):
     def test_traversals(self, remote_connection_http):
         statics.load_statics(globals())
@@ -149,6 +158,17 @@ class TestDriverRemoteConnectionHttp(object):
         except StopIteration:
             assert True
 
+    def test_lambda_traversals(self, remote_connection_http):
+        statics.load_statics(globals())
+        assert "remoteconnection[{},gmodern]".format(test_no_auth_http_url) == str(remote_connection_http)
+        g = traversal().withRemote(remote_connection_http)
+
+        assert 24.0 == g.withSack(1.0, lambda: ("x -> x + 1", "gremlin-groovy")).V().both().sack().sum_().next()
+        assert 24.0 == g.withSack(lambda: ("{1.0d}", "gremlin-groovy"), lambda: ("x -> x + 1", "gremlin-groovy")).V().both().sack().sum_().next()
+
+        assert 48.0 == g.withSack(1.0, lambda: ("x, y ->  x + y + 1", "gremlin-groovy")).V().both().sack().sum_().next()
+        assert 48.0 == g.withSack(lambda: ("{1.0d}", "gremlin-groovy"), lambda: ("x, y ->  x + y + 1", "gremlin-groovy")).V().both().sack().sum_().next()
+
     def test_strategies(self, remote_connection_http):
         statics.load_statics(globals())
         g = traversal().withRemote(remote_connection_http). \
diff --git a/gremlin-python/src/main/python/tests/process/test_translator.py b/gremlin-python/src/main/python/tests/process/test_translator.py
index 8a121a5437..eb055e2543 100644
--- a/gremlin-python/src/main/python/tests/process/test_translator.py
+++ b/gremlin-python/src/main/python/tests/process/test_translator.py
@@ -36,293 +36,298 @@ class TestTranslator(object):
         tests = list()
         # 0
         tests.append([g.V(),
-                     "g.V()"])
+                      "g.V()"])
         # 1
         tests.append([g.V('1', '2', '3', '4'),
-                     "g.V('1','2','3','4')"])
+                      "g.V('1','2','3','4')"])
         # 2
         tests.append([g.V('3').valueMap(True),
-                     "g.V('3').valueMap(true)"])
+                      "g.V('3').valueMap(true)"])
         # 3
         tests.append([g.V().constant(5),
-                     "g.V().constant(5)"])
+                      "g.V().constant(5)"])
         # 4
         tests.append([g.V().constant(1.5),
-                     "g.V().constant(1.5)"])
+                      "g.V().constant(1.5d)"])
         # 5
         tests.append([g.V().constant('Hello'),
-                     "g.V().constant('Hello')"])
+                      "g.V().constant('Hello')"])
         # 6
         tests.append([g.V().hasLabel('airport').limit(5),
-                     "g.V().hasLabel('airport').limit(5)"])
+                      "g.V().hasLabel('airport').limit(5)"])
         # 7
         tests.append([g.V().hasLabel(within('a', 'b', 'c')),
-                     "g.V().hasLabel(within(['a','b','c']))"])
+                      "g.V().hasLabel(within(['a','b','c']))"])
         # 8
         tests.append([g.V().hasLabel('airport', 'continent').out().limit(5),
-                     "g.V().hasLabel('airport','continent').out().limit(5)"])
+                      "g.V().hasLabel('airport','continent').out().limit(5)"])
         # 9
         tests.append([g.V().hasLabel('airport').out().values('code').limit(5),
-                     "g.V().hasLabel('airport').out().values('code').limit(5)"])
+                      "g.V().hasLabel('airport').out().values('code').limit(5)"])
         # 10
         tests.append([g.V('3').as_('a').out('route').limit(10).where(eq('a')).by('region'),
-                     "g.V('3').as('a').out('route').limit(10).where(eq('a')).by('region')"])
+                      "g.V('3').as('a').out('route').limit(10).where(eq('a')).by('region')"])
         # 11
         tests.append([g.V('3').repeat(__.out('route').simplePath()).times(2).path().by('code'),
-                     "g.V('3').repeat(__.out('route').simplePath()).times(2).path().by('code')"])
+                      "g.V('3').repeat(__.out('route').simplePath()).times(2).path().by('code')"])
         # 12
         tests.append([g.V().hasLabel('airport').out().has('region', 'US-TX').values('code').limit(5),
-                     "g.V().hasLabel('airport').out().has('region','US-TX').values('code').limit(5)"])
+                      "g.V().hasLabel('airport').out().has('region','US-TX').values('code').limit(5)"])
         # 13
         tests.append([g.V().hasLabel('airport').union(__.values('city'), __.values('region')).limit(5),
-                     "g.V().hasLabel('airport').union(__.values('city'),__.values('region')).limit(5)"])
+                      "g.V().hasLabel('airport').union(__.values('city'),__.values('region')).limit(5)"])
         # 14
         tests.append([g.V('3').as_('a').out('route', 'routes'),
-                     "g.V('3').as('a').out('route','routes')"])
+                      "g.V('3').as('a').out('route','routes')"])
         # 15
         tests.append([g.V().where(__.values('runways').is_(5)),
-                    "g.V().where(__.values('runways').is(5))"])
+                      "g.V().where(__.values('runways').is(5))"])
         # 16
         tests.append([g.V('3').repeat(__.out().simplePath()).until(__.has('code', 'AGR')).path().by('code').limit(5),
-                     "g.V('3').repeat(__.out().simplePath()).until(__.has('code','AGR')).path().by('code').limit(5)"])
+                      "g.V('3').repeat(__.out().simplePath()).until(__.has('code','AGR')).path().by('code').limit(5)"])
         # 17
         tests.append([g.V().hasLabel('airport').order().by(__.id_()),
-                     "g.V().hasLabel('airport').order().by(__.id())"])
+                      "g.V().hasLabel('airport').order().by(__.id())"])
         # 18
         tests.append([g.V().hasLabel('airport').order().by(T.id),
-                     "g.V().hasLabel('airport').order().by(T.id)"])
+                      "g.V().hasLabel('airport').order().by(T.id)"])
         # 19
-        tests.append([g.V().hasLabel('airport').order().by(__.id_(),Order.desc),
-                     "g.V().hasLabel('airport').order().by(__.id(),Order.desc)"])
+        tests.append([g.V().hasLabel('airport').order().by(__.id_(), Order.desc),
+                      "g.V().hasLabel('airport').order().by(__.id(),Order.desc)"])
         # 20
-        tests.append([g.V().hasLabel('airport').order().by('code',Order.desc),
-                     "g.V().hasLabel('airport').order().by('code',Order.desc)"])
+        tests.append([g.V().hasLabel('airport').order().by('code', Order.desc),
+                      "g.V().hasLabel('airport').order().by('code',Order.desc)"])
         # 21
         tests.append([g.V('1', '2', '3').local(__.out().out().dedup().fold()),
-                     "g.V('1','2','3').local(__.out().out().dedup().fold())"])
+                      "g.V('1','2','3').local(__.out().out().dedup().fold())"])
         # 22
         tests.append([g.V('3').out().path().count(Scope.local),
-                     "g.V('3').out().path().count(Scope.local)"])
+                      "g.V('3').out().path().count(Scope.local)"])
         # 23
         tests.append([g.E().count(),
-                     "g.E().count()"])
+                      "g.E().count()"])
         # 24
         tests.append([g.V('5').outE('route').inV().path().limit(10),
-                     "g.V('5').outE('route').inV().path().limit(10)"])
+                      "g.V('5').outE('route').inV().path().limit(10)"])
         # 25
         tests.append([g.V('5').propertyMap().select(Column.keys),
-                     "g.V('5').propertyMap().select(Column.keys)"])
+                      "g.V('5').propertyMap().select(Column.keys)"])
         # 26
         tests.append([g.V('5').propertyMap().select(Column.values),
-                     "g.V('5').propertyMap().select(Column.values)"])
+                      "g.V('5').propertyMap().select(Column.values)"])
         # 27
         tests.append([g.V('3').values('runways').math('_ + 1'),
-                     "g.V('3').values('runways').math('_ + 1')"])
+                      "g.V('3').values('runways').math('_ + 1')"])
         # 28
         tests.append([g.V('3').emit().repeat(__.out().simplePath()).times(3).limit(5).path(),
-                     "g.V('3').emit().repeat(__.out().simplePath()).times(3).limit(5).path()"])
+                      "g.V('3').emit().repeat(__.out().simplePath()).times(3).limit(5).path()"])
         # 29
         tests.append([g.V().match(__.as_('a').has('code', 'LHR').as_('b')).select('b').by('code'),
-                     "g.V().match(__.as('a').has('code','LHR').as('b')).select('b').by('code')"])
+                      "g.V().match(__.as('a').has('code','LHR').as('b')).select('b').by('code')"])
         # 30
         tests.append([g.V().has('test-using-keyword-as-property', 'repeat'),
-                     "g.V().has('test-using-keyword-as-property','repeat')"])
+                      "g.V().has('test-using-keyword-as-property','repeat')"])
         # 31
         tests.append([g.V('1').addE('test').to(__.V('4')),
-                     "g.V('1').addE('test').to(__.V('4'))"])
+                      "g.V('1').addE('test').to(__.V('4'))"])
         # 32
         tests.append([g.V().values('runways').max_(),
-                     "g.V().values('runways').max()"])
+                      "g.V().values('runways').max()"])
         # 33
         tests.append([g.V().values('runways').min_(),
-                     "g.V().values('runways').min()"])
+                      "g.V().values('runways').min()"])
         # 34
         tests.append([g.V().values('runways').sum_(),
-                     "g.V().values('runways').sum()"])
+                      "g.V().values('runways').sum()"])
         # 35
         tests.append([g.V().values('runways').mean(),
-                     "g.V().values('runways').mean()"])
+                      "g.V().values('runways').mean()"])
         # 36
         tests.append([g.withSack(0).V('3', '5').sack(Operator.sum_).by('runways').sack(),
-                     "g.withSack(0).V('3','5').sack(Operator.sum).by('runways').sack()"])
+                      "g.withSack(0).V('3','5').sack(Operator.sum).by('runways').sack()"])
         # 37
-        tests.append([g.V('3').values('runways').store('x').V('4').values('runways').store('x').by(__.constant(1)).V('6').store('x').by(__.constant(1)).select('x').unfold().sum_(),
-                     "g.V('3').values('runways').store('x').V('4').values('runways').store('x').by(__.constant(1)).V('6').store('x').by(__.constant(1)).select('x').unfold().sum()"])
+        tests.append([g.V('3').values('runways').store('x').V('4').values('runways').store('x').by(__.constant(1)).V(
+            '6').store('x').by(__.constant(1)).select('x').unfold().sum_(),
+                      "g.V('3').values('runways').store('x').V('4').values('runways').store('x').by(__.constant(1)).V('6').store('x').by(__.constant(1)).select('x').unfold().sum()"])
         # 38
         tests.append([g.inject(3, 4, 5),
-                     "g.inject(3,4,5)"])
+                      "g.inject(3,4,5)"])
         # 39
         tests.append([g.inject([3, 4, 5]),
-                     "g.inject([3, 4, 5])"])
+                      "g.inject([3,4,5])"])
         # 40
         tests.append([g.inject(3, 4, 5).count(),
-                     "g.inject(3,4,5).count()"])
+                      "g.inject(3,4,5).count()"])
         # 41
         tests.append([g.V().has('runways', gt(5)).count(),
-                     "g.V().has('runways',gt(5)).count()"])
+                      "g.V().has('runways',gt(5)).count()"])
         # 42
         tests.append([g.V().has('runways', lte(5.3)).count(),
-                     "g.V().has('runways',lte(5.3)).count()"])
+                      "g.V().has('runways',lte(5.3d)).count()"])
         # 43
-        tests.append([g.V().has('code', within(123,124)),
-                     "g.V().has('code',within([123,124]))"])
+        tests.append([g.V().has('code', within(123, 124)),
+                      "g.V().has('code',within([123,124]))"])
         # 44
         tests.append([g.V().has('code', within(123, 'abc')),
-                     "g.V().has('code',within([123,'abc']))"])
+                      "g.V().has('code',within([123,'abc']))"])
         # 45
         tests.append([g.V().has('code', within('abc', 123)),
-                     "g.V().has('code',within(['abc',123]))"])
+                      "g.V().has('code',within(['abc',123]))"])
         # 46
         tests.append([g.V().has('code', within('abc', 'xyz')),
-                     "g.V().has('code',within(['abc','xyz']))"])
+                      "g.V().has('code',within(['abc','xyz']))"])
         # 47
-        tests.append([g.V('1', '2').has('region', P.within('US-TX','US-GA')),
-                     "g.V('1','2').has('region',within(['US-TX','US-GA']))"])
+        tests.append([g.V('1', '2').has('region', P.within('US-TX', 'US-GA')),
+                      "g.V('1','2').has('region',within(['US-TX','US-GA']))"])
         # 48
         tests.append([g.V().and_(__.has('runways', P.gt(5)), __.has('region', 'US-TX')),
-                     "g.V().and(__.has('runways',gt(5)),__.has('region','US-TX'))"])
+                      "g.V().and(__.has('runways',gt(5)),__.has('region','US-TX'))"])
         # 49
         tests.append([g.V().union(__.has('runways', gt(5)), __.has('region', 'US-TX')),
-                     "g.V().union(__.has('runways',gt(5)),__.has('region','US-TX'))"])
+                      "g.V().union(__.has('runways',gt(5)),__.has('region','US-TX'))"])
         # 50
-        tests.append([g.V('3').choose(__.values('runways').is_(3), __.constant('three'),__.constant('not three')),
-                     "g.V('3').choose(__.values('runways').is(3),__.constant('three'),__.constant('not three'))"])
+        tests.append([g.V('3').choose(__.values('runways').is_(3), __.constant('three'), __.constant('not three')),
+                      "g.V('3').choose(__.values('runways').is(3),__.constant('three'),__.constant('not three'))"])
         # 51
-        tests.append([g.V('3').choose(__.values('runways')).option(1, __.constant('three')).option(2,__.constant('not three')),
-                     "g.V('3').choose(__.values('runways')).option(1,__.constant('three')).option(2,__.constant('not three'))"])
+        tests.append(
+            [g.V('3').choose(__.values('runways')).option(1, __.constant('three')).option(2, __.constant('not three')),
+             "g.V('3').choose(__.values('runways')).option(1,__.constant('three')).option(2,__.constant('not three'))"])
         # 52
-        tests.append([g.V('3').choose(__.values('runways')).option(1.5, __.constant('one and a half')).option(2,__.constant('not three')),
-                     "g.V('3').choose(__.values('runways')).option(1.5,__.constant('one and a half')).option(2,__.constant('not three'))"])
+        tests.append([g.V('3').choose(__.values('runways')).option(1.5, __.constant('one and a half')).option(2,
+                                                                                                              __.constant(
+                                                                                                                  'not three')),
+                      "g.V('3').choose(__.values('runways')).option(1.5d,__.constant('one and a half')).option(2,__.constant('not three'))"])
         # 53
         tests.append([g.V('3').repeat(__.out().simplePath()).until(__.loops().is_(1)).count(),
-                     "g.V('3').repeat(__.out().simplePath()).until(__.loops().is(1)).count()"])
+                      "g.V('3').repeat(__.out().simplePath()).until(__.loops().is(1)).count()"])
         # 54
-        tests.append([g.V().hasLabel('airport').limit(20).group().by('region').by('code').order(Scope.local).by(Column.keys),
-                     "g.V().hasLabel('airport').limit(20).group().by('region').by('code').order(Scope.local).by(Column.keys)"])
+        tests.append(
+            [g.V().hasLabel('airport').limit(20).group().by('region').by('code').order(Scope.local).by(Column.keys),
+             "g.V().hasLabel('airport').limit(20).group().by('region').by('code').order(Scope.local).by(Column.keys)"])
         # 55
         tests.append([g.V('1').as_('a').V('2').as_('a').select(Pop.all_, 'a'),
-                     "g.V('1').as('a').V('2').as('a').select(Pop.all,'a')"])
+                      "g.V('1').as('a').V('2').as('a').select(Pop.all,'a')"])
         # 56
         tests.append([g.addV('test').property(Cardinality.set_, 'p1', 10),
-                     "g.addV('test').property(Cardinality.set,'p1',10)"])
+                      "g.addV('test').property(Cardinality.set,'p1',10)"])
         # 57
         tests.append([g.addV('test').property(Cardinality.list_, 'p1', 10),
-                     "g.addV('test').property(Cardinality.list,'p1',10)"])
+                      "g.addV('test').property(Cardinality.list,'p1',10)"])
 
         # 58
         tests.append([g.addV('test').property(Cardinality.single, 'p1', 10),
-                     "g.addV('test').property(Cardinality.single,'p1',10)"])
+                      "g.addV('test').property(Cardinality.single,'p1',10)"])
         # 59
         tests.append([g.V().limit(5).order().by(T.label),
-                     "g.V().limit(5).order().by(T.label)"])
+                      "g.V().limit(5).order().by(T.label)"])
 
         # 60
         tests.append([g.V().range_(1, 5),
-                     "g.V().range(1,5)"])
+                      "g.V().range(1,5)"])
 
         # 61
         tests.append([g.addV('test').property('p1', 123),
-                     "g.addV('test').property('p1',123)"])
+                      "g.addV('test').property('p1',123)"])
 
         # 62
-        tests.append([g.addV('test').property('date',datetime(2021, 2, 1, 9, 30)),
-                     "g.addV('test').property('date',new Date(121,2,1,9,30,0))"])
+        tests.append([g.addV('test').property('date', datetime(2021, 2, 1, 9, 30)),
+                      "g.addV('test').property('date',new Date(121,2,1,9,30,0))"])
         # 63
-        tests.append([g.addV('test').property('date',datetime(2021, 2, 1)),
-                     "g.addV('test').property('date',new Date(121,2,1,0,0,0))"])
+        tests.append([g.addV('test').property('date', datetime(2021, 2, 1)),
+                      "g.addV('test').property('date',new Date(121,2,1,0,0,0))"])
         # 64
         tests.append([g.addE('route').from_(__.V('1')).to(__.V('2')),
-                     "g.addE('route').from(__.V('1')).to(__.V('2'))"])
+                      "g.addE('route').from(__.V('1')).to(__.V('2'))"])
         # 65
         tests.append([g.withSideEffect('a', [1, 2]).V('3').select('a'),
-                     "g.withSideEffect('a',[1, 2]).V('3').select('a')"])
+                      "g.withSideEffect('a',[1,2]).V('3').select('a')"])
         # 66
         tests.append([g.withSideEffect('a', 1).V('3').select('a'),
-                     "g.withSideEffect('a',1).V('3').select('a')"])
+                      "g.withSideEffect('a',1).V('3').select('a')"])
         # 67
         tests.append([g.withSideEffect('a', 'abc').V('3').select('a'),
-                     "g.withSideEffect('a','abc').V('3').select('a')"])
+                      "g.withSideEffect('a','abc').V('3').select('a')"])
         # 68
         tests.append([g.V().has('airport', 'region', 'US-NM').limit(3).values('elev').fold().index(),
-                     "g.V().has('airport','region','US-NM').limit(3).values('elev').fold().index()"])
+                      "g.V().has('airport','region','US-NM').limit(3).values('elev').fold().index()"])
         # 69
         tests.append([g.V('3').repeat(__.timeLimit(1000).out().simplePath()).until(__.has('code', 'AGR')).path(),
-                     "g.V('3').repeat(__.timeLimit(1000).out().simplePath()).until(__.has('code','AGR')).path()"])
+                      "g.V('3').repeat(__.timeLimit(1000).out().simplePath()).until(__.has('code','AGR')).path()"])
 
         # 70
         tests.append([g.V().hasLabel('airport').where(__.values('elev').is_(gt(14000))),
-                     "g.V().hasLabel('airport').where(__.values('elev').is(gt(14000)))"])
+                      "g.V().hasLabel('airport').where(__.values('elev').is(gt(14000)))"])
 
         # 71
         tests.append([g.V().hasLabel('airport').where(__.out().count().is_(gt(250))).values('code'),
-                     "g.V().hasLabel('airport').where(__.out().count().is(gt(250))).values('code')"])
+                      "g.V().hasLabel('airport').where(__.out().count().is(gt(250))).values('code')"])
 
         # 72
         tests.append([g.V().hasLabel('airport').filter_(__.out().count().is_(gt(250))).values('code'),
-                     "g.V().hasLabel('airport').filter(__.out().count().is(gt(250))).values('code')"])
+                      "g.V().hasLabel('airport').filter(__.out().count().is(gt(250))).values('code')"])
         # 73
         tests.append([g.withSack(0).
-                        V('3').
-                        repeat(__.outE('route').sack(Operator.sum_).by('dist').inV()).
-                        until(__.has('code', 'AGR').or_().loops().is_(4)).
-                        has('code', 'AGR').
-                        local(__.union(__.path().by('code').by('dist'),__.sack()).fold()).
-                        limit(10),
-                     "g.withSack(0).V('3').repeat(__.outE('route').sack(Operator.sum).by('dist').inV()).until(__.has('code','AGR').or().loops().is(4)).has('code','AGR').local(__.union(__.path().by('code').by('dist'),__.sack()).fold()).limit(10)"])
+                     V('3').
+                     repeat(__.outE('route').sack(Operator.sum_).by('dist').inV()).
+                     until(__.has('code', 'AGR').or_().loops().is_(4)).
+                     has('code', 'AGR').
+                     local(__.union(__.path().by('code').by('dist'), __.sack()).fold()).
+                     limit(10),
+                      "g.withSack(0).V('3').repeat(__.outE('route').sack(Operator.sum).by('dist').inV()).until(__.has('code','AGR').or().loops().is(4)).has('code','AGR').local(__.union(__.path().by('code').by('dist'),__.sack()).fold()).limit(10)"])
 
         # 74
         tests.append([g.addV().as_('a').addV().as_('b').addE('knows').from_('a').to('b'),
-                     "g.addV().as('a').addV().as('b').addE('knows').from('a').to('b')"])
+                      "g.addV().as('a').addV().as('b').addE('knows').from('a').to('b')"])
 
         # 75
         tests.append([g.addV('Person').as_('a').addV('Person').as_('b').addE('knows').from_('a').to('b'),
-                     "g.addV('Person').as('a').addV('Person').as('b').addE('knows').from('a').to('b')"])
+                      "g.addV('Person').as('a').addV('Person').as('b').addE('knows').from('a').to('b')"])
         # 76
-        tests.append([g.V('3').project('Out','In').by(__.out().count()).by(__.in_().count()),
-                     "g.V('3').project('Out','In').by(__.out().count()).by(__.in().count())"])
+        tests.append([g.V('3').project('Out', 'In').by(__.out().count()).by(__.in_().count()),
+                      "g.V('3').project('Out','In').by(__.out().count()).by(__.in().count())"])
         # 77
         tests.append([g.V('44').out().aggregate('a').out().where(within('a')).path(),
-                     "g.V('44').out().aggregate('a').out().where(within(['a'])).path()"])
+                      "g.V('44').out().aggregate('a').out().where(within(['a'])).path()"])
         # 78
         tests.append([g.V().has('date', datetime(2021, 2, 22)),
-                     "g.V().has('date',new Date(121,2,22,0,0,0))"])
+                      "g.V().has('date',new Date(121,2,22,0,0,0))"])
         # 79
         tests.append([g.V().has('date', within(datetime(2021, 2, 22), datetime(2021, 1, 1))),
                       "g.V().has('date',within([new Date(121,2,22,0,0,0),new Date(121,1,1,0,0,0)]))"])
         # 80
         tests.append([g.V().has('date', between(datetime(2021, 1, 1), datetime(2021, 2, 22))),
-                                "g.V().has('date',between(new Date(121,1,1,0,0,0),new Date(121,2,22,0,0,0)))"])
+                      "g.V().has('date',between(new Date(121,1,1,0,0,0),new Date(121,2,22,0,0,0)))"])
         # 81
-        tests.append([g.V().has('date', inside(datetime(2021, 1, 1),datetime(2021, 2, 22))),
-                                "g.V().has('date',inside(new Date(121,1,1,0,0,0),new Date(121,2,22,0,0,0)))"])
+        tests.append([g.V().has('date', inside(datetime(2021, 1, 1), datetime(2021, 2, 22))),
+                      "g.V().has('date',inside(new Date(121,1,1,0,0,0),new Date(121,2,22,0,0,0)))"])
         # 82
         tests.append([g.V().has('date', P.gt(datetime(2021, 1, 1, 9, 30))),
-                     "g.V().has('date',gt(new Date(121,1,1,9,30,0)))"])
+                      "g.V().has('date',gt(new Date(121,1,1,9,30,0)))"])
         # 83
-        tests.append([g.V().has('runways', between(3,5)),
-                     "g.V().has('runways',between(3,5))"])
+        tests.append([g.V().has('runways', between(3, 5)),
+                      "g.V().has('runways',between(3,5))"])
         # 84
-        tests.append([g.V().has('runways', inside(3,5)),
-                     "g.V().has('runways',inside(3,5))"])
+        tests.append([g.V().has('runways', inside(3, 5)),
+                      "g.V().has('runways',inside(3,5))"])
         # 85
         tests.append([g.V('44').outE().elementMap(),
-                     "g.V('44').outE().elementMap()"])
+                      "g.V('44').outE().elementMap()"])
         # 86
         tests.append([g.V('44').valueMap().by(__.unfold()),
-                     "g.V('44').valueMap().by(__.unfold())"])
+                      "g.V('44').valueMap().by(__.unfold())"])
         # 87
-        tests.append([g.V('44').valueMap().with_(WithOptions.tokens,WithOptions.labels),
-                     "g.V('44').valueMap().with(WithOptions.tokens,WithOptions.labels)"])
+        tests.append([g.V('44').valueMap().with_(WithOptions.tokens, WithOptions.labels),
+                      "g.V('44').valueMap().with(WithOptions.tokens,WithOptions.labels)"])
         # 88
         tests.append([g.V('44').valueMap().with_(WithOptions.tokens),
-                     "g.V('44').valueMap().with(WithOptions.tokens)"])
+                      "g.V('44').valueMap().with(WithOptions.tokens)"])
         # 89
         tests.append([g.withStrategies(ReadOnlyStrategy()).addV('test'),
                       "g.withStrategies(ReadOnlyStrategy).addV('test')"])
         # 90
         strategy = SubgraphStrategy(vertices=__.has('region', 'US-TX'), edges=__.hasLabel('route'))
         tests.append([g.withStrategies(strategy).V().count(),
-                    "g.withStrategies(new SubgraphStrategy(vertices:__.has('region','US-TX'),edges:__.hasLabel('route'))).V().count()"])
+                      "g.withStrategies(new SubgraphStrategy(vertices:__.has('region','US-TX'),edges:__.hasLabel('route'))).V().count()"])
         # 91
         strategy = SubgraphStrategy(vertex_properties=__.hasNot('runways'))
         tests.append([g.withStrategies(strategy).V().count(),
@@ -333,7 +338,7 @@ class TestTranslator(object):
                       "g.withStrategies(new SubgraphStrategy(vertices:__.has('region','US-TX'),vertexProperties:__.hasNot('runways'))).V().count()"])
         # 93
         strategy = SubgraphStrategy(vertices=__.has('region', 'US-TX'), edges=__.hasLabel('route'))
-        tests.append([g.withStrategies(ReadOnlyStrategy(),strategy).V().count(),
+        tests.append([g.withStrategies(ReadOnlyStrategy(), strategy).V().count(),
                       "g.withStrategies(ReadOnlyStrategy,new SubgraphStrategy(vertices:__.has('region','US-TX'),edges:__.hasLabel('route'))).V().count()"])
         # 94
         strategy = SubgraphStrategy(vertices=__.has('region', 'US-TX'))
@@ -344,35 +349,37 @@ class TestTranslator(object):
                       "g.withStrategies(new OptionsStrategy(evaluationTimeout:500)).V().count()"])
         # 96
         tests.append([g.withStrategies(OptionsStrategy({'evaluationTimeout': 500})).V().count(),
-                     "g.withStrategies(new OptionsStrategy(evaluationTimeout:500)).V().count()"])
+                      "g.withStrategies(new OptionsStrategy(evaluationTimeout:500)).V().count()"])
         # 97
-        tests.append([g.withStrategies(PartitionStrategy(partition_key="partition", write_partition="a", read_partitions=["a"])).addV('test'),
-                     "g.withStrategies(new PartitionStrategy(partitionKey:'partition',writePartition:'a',readPartitions:['a'])).addV('test')"])
+        tests.append([g.withStrategies(
+            PartitionStrategy(partition_key="partition", write_partition="a", read_partitions=["a"])).addV('test'),
+                      "g.withStrategies(new PartitionStrategy(partitionKey:'partition',writePartition:'a',readPartitions:['a'])).addV('test')"])
         # 98
-        tests.append([g.withComputer().V().shortestPath().with_(ShortestPath.target, __.has('name','peter')),
-                     "g.withStrategies(VertexProgramStrategy).V().shortestPath().with('~tinkerpop.shortestPath.target',__.has('name','peter'))"])
+        tests.append([g.withComputer().V().shortestPath().with_(ShortestPath.target, __.has('name', 'peter')),
+                      "g.withStrategies(VertexProgramStrategy).V().shortestPath().with('~tinkerpop.shortestPath.target',__.has('name','peter'))"])
 
         # 99
         tests.append([g.V().has("p1", starting_with("foo")),
-                     "g.V().has('p1',startingWith('foo'))"])
+                      "g.V().has('p1',startingWith('foo'))"])
 
         # 100
         tests.append([g.V().has("p1", ending_with("foo")),
-                     "g.V().has('p1',endingWith('foo'))"])
+                      "g.V().has('p1',endingWith('foo'))"])
 
         # 101
         class SuperStr(str):
             pass
+
         tests.append([g.V(SuperStr("foo_id")),
-                     "g.V('foo_id')"])
+                      "g.V('foo_id')"])
 
         # 102
         tests.append([g.V().has("p1", containing(SuperStr("foo"))),
-                     "g.V().has('p1',containing('foo'))"])
+                      "g.V().has('p1',containing('foo'))"])
 
         # 103
         tests.append([g.V().has("p1", None),
-                     "g.V().has('p1',null)"])
+                      "g.V().has('p1',null)"])
 
         # 104
         vertex = Vertex(0, "person")
@@ -399,6 +406,31 @@ class TestTranslator(object):
         tests.append([g.V().has('person', 'age', Bindings.of('x', P.lt(30))).count(),
                       "g.V().has('person','age',Bindings.instance().of('x', lt(30))).count()"])
 
+        # 109
+        tests.append([g.inject({'name': 'java'}, {T.id: 0}, {},
+                               {'age': float(10), 'pos_inf': float("inf"), 'neg_inf': float("-inf"), 'nan': float("nan")}),
+                      "g.inject(['name':'java'],[(T.id):0],[:],['age':10.0d,'pos_inf':Double.POSITIVE_INFINITY,'neg_inf':Double.NEGATIVE_INFINITY,'nan':Double.NaN])"])
+
+        # 110
+        tests.append([g.inject(float(1)).is_(P.eq(1).or_(P.gt(2)).or_(P.lte(3)).or_(P.gte(4))),
+                      "g.inject(1.0d).is(eq(1).or(gt(2)).or(lte(3)).or(gte(4)))"])
+
+        # 111
+        tests.append([g.V().hasLabel('person').has('age',P.gt(10).or_(P.gte(11).and_(P.lt(20))).and_(P.lt(29).or_(P.eq(35)))).name,
+                      "g.V().hasLabel('person').has('age',gt(10).or(gte(11).and(lt(20))).and(lt(29).or(eq(35)))).values('name')"])
+
+        # 112
+        tests.append([g.inject(set(('a'))),
+                      "g.inject(['a'] as Set)"])
+
+        # 113
+        tests.append([g.merge_v(None),
+                      "g.mergeV((Traversal) null)"])
+
+        # 114
+        tests.append([g.merge_e(None),
+                      "g.mergeE((Traversal) null)"])
+
         tlr = Translator().of('g')
 
         for t in range(len(tests)):