You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by ok...@apache.org on 2016/10/07 16:12:00 UTC
tinkerpop git commit: added and removing strategies from a traversal
source in Python is sooooooooo elegant. Mapped the strategies from Gremlin
JVM, to Python. Add a good body of test cases.
Repository: tinkerpop
Updated Branches:
refs/heads/TINKERPOP-1455-redux 027959811 -> f84b19637
added and removing strategies from a traversal source in Python is sooooooooo elegant. Mapped the strategies from Gremlin JVM, to Python. Add a good body of test cases.
Project: http://git-wip-us.apache.org/repos/asf/tinkerpop/repo
Commit: http://git-wip-us.apache.org/repos/asf/tinkerpop/commit/f84b1963
Tree: http://git-wip-us.apache.org/repos/asf/tinkerpop/tree/f84b1963
Diff: http://git-wip-us.apache.org/repos/asf/tinkerpop/diff/f84b1963
Branch: refs/heads/TINKERPOP-1455-redux
Commit: f84b196372f89479472e9a39a0d885a866c9cdb4
Parents: 0279598
Author: Marko A. Rodriguez <ok...@gmail.com>
Authored: Fri Oct 7 10:11:52 2016 -0600
Committer: Marko A. Rodriguez <ok...@gmail.com>
Committed: Fri Oct 7 10:11:52 2016 -0600
----------------------------------------------------------------------
docs/src/reference/gremlin-variants.asciidoc | 12 +-
.../process/traversal/TraversalSource.java | 3 -
.../python/TraversalSourceGenerator.groovy | 22 ++-
.../jython/gremlin_python/process/strategies.py | 149 +++++++++++++++++++
.../jython/gremlin_python/process/traversal.py | 22 ++-
.../src/main/jython/gremlin_python/statics.py | 3 +-
.../gremlin_python/structure/io/graphson.py | 17 ++-
.../driver/test_driver_remote_connection.py | 11 +-
.../jython/tests/process/test_strategies.py | 106 +++++++++++++
.../jython/tests/structure/io/test_graphson.py | 17 ++-
10 files changed, 340 insertions(+), 22 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f84b1963/docs/src/reference/gremlin-variants.asciidoc
----------------------------------------------------------------------
diff --git a/docs/src/reference/gremlin-variants.asciidoc b/docs/src/reference/gremlin-variants.asciidoc
index 0001ba4..51e2d2b 100644
--- a/docs/src/reference/gremlin-variants.asciidoc
+++ b/docs/src/reference/gremlin-variants.asciidoc
@@ -229,20 +229,22 @@ Traversal Strategies
~~~~~~~~~~~~~~~~~~~~
In order to add and remove <<traversalstrategy,traversal strategies>> from a traversal source, Gremlin-Python has a
-`TraversalStrategy` class that can be used.
+`TraversalStrategy` class along with numerous subclasses that mirror the standard, distributed strategies.
[gremlin-python,modern]
----
-g = g.withStrategies(TraversalStrategy('SubgraphStrategy',{'vertices': hasLabel('person'),'edges': has('weight',gt(0.5))}))
+g = g.withStrategies(SubgraphStrategy(vertices=hasLabel('person'),edges=has('weight',gt(0.5))))
g.V().name.toList()
g.V().outE().valueMap(True).toList()
-g = g.withoutStrategies(TraversalStrategy('SubgraphStrategy'))
+g = g.withoutStrategies(SubgraphStrategy)
g.V().name.toList()
g.V().outE().valueMap(True).toList()
----
-IMPORTANT: Future work will include extending the Gremlin-Python `TraversalStrategy` class with mirrors of the Java-based
-Gremlin traversal machine strategies so the two variants have the same look-and-feel.
+NOTE: Many of the `TraversalStrategy` classes in Gremlin-Python are proxies to the respective strategy on the
+Apache TinkerPop's JVM-based Gremlin traversal machine. As such, their `apply(Traversal)` method does nothing. However,
+the strategy is encoded in the Gremlin-Python bytecode and transmittable to the Gremlin traversal machine for
+re-construction machine-side.
The Lambda Solution
~~~~~~~~~~~~~~~~~~~
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f84b1963/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java
----------------------------------------------------------------------
diff --git a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java
index de77ea5..fa697f6 100644
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/TraversalSource.java
@@ -33,9 +33,6 @@ import org.apache.tinkerpop.gremlin.util.function.ConstantSupplier;
import java.io.Serializable;
import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BinaryOperator;
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f84b1963/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy b/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy
index 9534a0c..a12fe05 100644
--- a/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy
+++ b/gremlin-python/src/main/groovy/org/apache/tinkerpop/gremlin/python/TraversalSourceGenerator.groovy
@@ -70,6 +70,11 @@ class Traversal(object):
self.last_traverser = None
def __repr__(self):
return str(self.bytecode)
+ def __eq__(self, other):
+ if isinstance(other, self.__class__):
+ return self.bytecode == other.bytecode
+ else:
+ return False
def __iter__(self):
return self
def __next__(self):
@@ -220,14 +225,22 @@ class TraversalStrategies(object):
def apply_strategies(self, traversal):
for traversal_strategy in self.traversal_strategies:
traversal_strategy.apply(traversal)
+ def __repr__(self):
+ return str(self.traversal_strategies)
class TraversalStrategy(object):
- def __init__(self, strategy_name, configuration=None):
- self.strategy_name = strategy_name
+ def __init__(self, strategy_name=None, configuration=None):
+ self.strategy_name = type(self).__name__ if strategy_name is None else strategy_name
self.configuration = {} if configuration is None else configuration
def apply(self, traversal):
return
+ def __eq__(self, other):
+ return isinstance(other, self.__class__)
+ def __hash__(self):
+ return hash(self.strategy_name)
+ def __repr__(self):
+ return self.strategy_name
'''
BYTECODE
@@ -251,6 +264,11 @@ class Bytecode(object):
for arg in args:
instruction.append(self.__convertArgument(arg))
self.step_instructions.append(instruction)
+ def __eq__(self, other):
+ if isinstance(other, self.__class__):
+ return self.source_instructions == other.source_instructions and self.step_instructions == other.step_instructions
+ else:
+ return False
def __convertArgument(self,arg):
if isinstance(arg, Traversal):
self.bindings.update(arg.bytecode.bindings)
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f84b1963/gremlin-python/src/main/jython/gremlin_python/process/strategies.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/process/strategies.py b/gremlin-python/src/main/jython/gremlin_python/process/strategies.py
new file mode 100644
index 0000000..db9e094
--- /dev/null
+++ b/gremlin-python/src/main/jython/gremlin_python/process/strategies.py
@@ -0,0 +1,149 @@
+'''
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+'''
+
+__author__ = 'Marko A. Rodriguez (http://markorodriguez.com)'
+
+from gremlin_python.process.traversal import TraversalStrategy
+
+
+#########################
+# DECORATION STRATEGIES #
+#########################
+
+class ConnectiveStrategy(TraversalStrategy):
+ def __init__(self):
+ TraversalStrategy.__init__(self)
+
+
+class ElementIdStrategy(TraversalStrategy):
+ def __init__(self):
+ TraversalStrategy.__init__(self)
+
+
+class HaltedTraverserStrategy(TraversalStrategy):
+ def __init__(self, haltedTraverserFactory="detached"):
+ TraversalStrategy.__init__(self, configuration={"haltedTraverserFactory": haltedTraverserFactory})
+
+
+class PartitionStrategy(TraversalStrategy):
+ def __init__(self, partitionKey, writePartition=None, readPartitions=None, includeMetaProperties=False):
+ TraversalStrategy.__init__(self, configuration={"partitionKey": partitionKey,
+ "includeMetaProperties": includeMetaProperties})
+ if writePartition is not None:
+ self.configuration["writePartition"] = writePartition
+ if writePartition is not None:
+ self.configuration["readPartitions"] = readPartitions
+
+
+class SubgraphStrategy(TraversalStrategy):
+ def __init__(self, vertices=None, edges=None, vertexProperties=None):
+ TraversalStrategy.__init__(self)
+ if vertices is not None:
+ self.configuration["vertices"] = vertices
+ if edges is not None:
+ self.configuration["edges"] = edges
+ if vertexProperties is not None:
+ self.configuration["vertexProperties"] = vertexProperties
+
+
+###########################
+# FINALIZATION STRATEGIES #
+###########################
+
+class MatchAlgorithmStrategy(TraversalStrategy):
+ def __init__(self, matchAlgorithm="count"):
+ TraversalStrategy.__init__(self, configuration={"matchAlgorithm": matchAlgorithm})
+
+
+###########################
+# OPTIMIZATION STRATEGIES #
+###########################
+
+class AdjacentToIncidentStrategy(TraversalStrategy):
+ def __init__(self):
+ TraversalStrategy.__init__(self)
+
+
+class FilterRankingStrategy(TraversalStrategy):
+ def __init__(self):
+ TraversalStrategy.__init__(self)
+
+
+class IdentityRemoveStrategy(TraversalStrategy):
+ def __init__(self):
+ TraversalStrategy.__init__(self)
+
+
+class IncidentToAdjacentStrategy(TraversalStrategy):
+ def __init__(self):
+ TraversalStrategy.__init__(self)
+
+
+class InlineFilterStrategy(TraversalStrategy):
+ def __init__(self):
+ TraversalStrategy.__init__(self)
+
+
+class LazyBarrierStrategy(TraversalStrategy):
+ def __init__(self):
+ TraversalStrategy.__init__(self)
+
+
+class MatchPredicateStrategy(TraversalStrategy):
+ def __init__(self):
+ TraversalStrategy.__init__(self)
+
+
+class OrderLimitStrategy(TraversalStrategy):
+ def __init__(self):
+ TraversalStrategy.__init__(self)
+
+
+class PathProcessorStrategy(TraversalStrategy):
+ def __init__(self):
+ TraversalStrategy.__init__(self)
+
+
+class PathRetractionStrategy(TraversalStrategy):
+ def __init__(self):
+ TraversalStrategy.__init__(self)
+
+
+class RangeByIsCountStrategy(TraversalStrategy):
+ def __init__(self):
+ TraversalStrategy.__init__(self)
+
+
+class RepeatUnrollStrategy(TraversalStrategy):
+ def __init__(self):
+ TraversalStrategy.__init__(self)
+
+
+###########################
+# VERIFICATION STRATEGIES #
+###########################
+
+class LambdaRestrictionStrategy(TraversalStrategy):
+ def __init__(self):
+ TraversalStrategy.__init__(self)
+
+
+class ReadOnlyStrategy(TraversalStrategy):
+ def __init__(self):
+ TraversalStrategy.__init__(self)
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f84b1963/gremlin-python/src/main/jython/gremlin_python/process/traversal.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/process/traversal.py b/gremlin-python/src/main/jython/gremlin_python/process/traversal.py
index 6ca763e..4611541 100644
--- a/gremlin-python/src/main/jython/gremlin_python/process/traversal.py
+++ b/gremlin-python/src/main/jython/gremlin_python/process/traversal.py
@@ -33,6 +33,11 @@ class Traversal(object):
self.last_traverser = None
def __repr__(self):
return str(self.bytecode)
+ def __eq__(self, other):
+ if isinstance(other, self.__class__):
+ return self.bytecode == other.bytecode
+ else:
+ return False
def __iter__(self):
return self
def __next__(self):
@@ -279,14 +284,22 @@ class TraversalStrategies(object):
def apply_strategies(self, traversal):
for traversal_strategy in self.traversal_strategies:
traversal_strategy.apply(traversal)
+ def __repr__(self):
+ return str(self.traversal_strategies)
class TraversalStrategy(object):
- def __init__(self, strategy_name, configuration=None):
- self.strategy_name = strategy_name
+ def __init__(self, strategy_name=None, configuration=None):
+ self.strategy_name = type(self).__name__ if strategy_name is None else strategy_name
self.configuration = {} if configuration is None else configuration
def apply(self, traversal):
return
+ def __eq__(self, other):
+ return isinstance(other, self.__class__)
+ def __hash__(self):
+ return hash(self.strategy_name)
+ def __repr__(self):
+ return self.strategy_name
'''
BYTECODE
@@ -310,6 +323,11 @@ class Bytecode(object):
for arg in args:
instruction.append(self.__convertArgument(arg))
self.step_instructions.append(instruction)
+ def __eq__(self, other):
+ if isinstance(other, self.__class__):
+ return self.source_instructions == other.source_instructions and self.step_instructions == other.step_instructions
+ else:
+ return False
def __convertArgument(self,arg):
if isinstance(arg, Traversal):
self.bindings.update(arg.bytecode.bindings)
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f84b1963/gremlin-python/src/main/jython/gremlin_python/statics.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/statics.py b/gremlin-python/src/main/jython/gremlin_python/statics.py
index c827020..a1abf8e 100644
--- a/gremlin-python/src/main/jython/gremlin_python/statics.py
+++ b/gremlin-python/src/main/jython/gremlin_python/statics.py
@@ -28,12 +28,13 @@ if six.PY3:
FloatType = float
IntType = int
LongType = long
+ TypeType = type
else:
long = long
from types import FloatType
from types import IntType
from types import LongType
-
+ from types import TypeType
staticMethods = {}
staticEnums = {}
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f84b1963/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py b/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py
index 63ea463..248d319 100644
--- a/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py
+++ b/gremlin-python/src/main/jython/gremlin_python/structure/io/graphson.py
@@ -27,7 +27,7 @@ import six
from gremlin_python import statics
from gremlin_python.statics import (
- FloatType, FunctionType, IntType, LongType, long)
+ FloatType, FunctionType, IntType, LongType, long, TypeType)
from gremlin_python.process.traversal import Binding
from gremlin_python.process.traversal import Bytecode
from gremlin_python.process.traversal import P
@@ -183,6 +183,11 @@ class LambdaSerializer(GraphSONSerializer):
return _SymbolHelper.objectify("Lambda", dict)
+class TypeSerializer(GraphSONSerializer):
+ def _dictify(self, clazz):
+ return GraphSONWriter._dictify(clazz())
+
+
class NumberSerializer(GraphSONSerializer):
def _dictify(self, number):
if isinstance(number, bool): # python thinks that 0/1 integers are booleans
@@ -280,8 +285,11 @@ class _SymbolHelper(object):
return _SymbolHelper.symbolMap[symbol] if symbol in _SymbolHelper.symbolMap else symbol
@staticmethod
- def objectify(type, value, prefix="g"):
- return {_SymbolHelper._TYPE: prefix + ":" + type, _SymbolHelper._VALUE: value}
+ def objectify(type, value=None, prefix="g"):
+ object = {_SymbolHelper._TYPE: prefix + ":" + type}
+ if value is not None:
+ object[_SymbolHelper._VALUE] = value
+ return object
serializers = {
@@ -295,7 +303,8 @@ serializers = {
LongType: NumberSerializer(),
IntType: NumberSerializer(),
FloatType: NumberSerializer(),
- TraversalStrategy: TraversalStrategySerializer()
+ TypeType: TypeSerializer(),
+ TraversalStrategy: TraversalStrategySerializer(),
}
deserializers = {
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f84b1963/gremlin-python/src/main/jython/tests/driver/test_driver_remote_connection.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/tests/driver/test_driver_remote_connection.py b/gremlin-python/src/main/jython/tests/driver/test_driver_remote_connection.py
index 847d14d..0de045a 100644
--- a/gremlin-python/src/main/jython/tests/driver/test_driver_remote_connection.py
+++ b/gremlin-python/src/main/jython/tests/driver/test_driver_remote_connection.py
@@ -31,6 +31,7 @@ from gremlin_python.process.graph_traversal import __
from gremlin_python.structure.graph import Graph
from gremlin_python.structure.graph import Vertex
from gremlin_python.structure.io.graphson import GraphSONWriter
+from gremlin_python.process.strategies import SubgraphStrategy
class TestDriverRemoteConnection(TestCase):
@@ -75,7 +76,15 @@ class TestDriverRemoteConnection(TestCase):
assert 1 == g.V().label().dedup().count().next()
assert "person" == g.V().label().dedup().next()
#
- g = g.withoutStrategies(TraversalStrategy("SubgraphStrategy")). \
+ g = Graph().traversal().withRemote(connection). \
+ withStrategies(SubgraphStrategy(vertices=__.hasLabel("person"), edges=__.hasLabel("created")))
+ print GraphSONWriter.writeObject(g.bytecode)
+ assert 4 == g.V().count().next()
+ assert 0 == g.E().count().next()
+ assert 1 == g.V().label().dedup().count().next()
+ assert "person" == g.V().label().dedup().next()
+ #
+ g = g.withoutStrategies(SubgraphStrategy). \
withComputer({"workers": 4, "vertices": __.has("name", "marko"), "edges": __.limit(0)})
assert 1 == g.V().count().next()
assert 0 == g.E().count().next()
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f84b1963/gremlin-python/src/main/jython/tests/process/test_strategies.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/tests/process/test_strategies.py b/gremlin-python/src/main/jython/tests/process/test_strategies.py
new file mode 100644
index 0000000..6d1d2c3
--- /dev/null
+++ b/gremlin-python/src/main/jython/tests/process/test_strategies.py
@@ -0,0 +1,106 @@
+'''
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+'''
+
+__author__ = 'Marko A. Rodriguez (http://markorodriguez.com)'
+
+import unittest
+from unittest import TestCase
+
+from gremlin_python.structure.graph import Graph
+from gremlin_python.process.strategies import *
+from gremlin_python.process.graph_traversal import __
+
+
+class TestTraversalStrategies(TestCase):
+ def test_singletons(self):
+ g = Graph().traversal()
+ bytecode = g.withStrategies(ReadOnlyStrategy()).bytecode
+ assert 1 == len(bytecode.source_instructions)
+ assert 2 == len(bytecode.source_instructions[0])
+ assert "withStrategies" == bytecode.source_instructions[0][0]
+ assert ReadOnlyStrategy() == bytecode.source_instructions[0][1]
+ assert "ReadOnlyStrategy" == str(bytecode.source_instructions[0][1])
+ assert hash(ReadOnlyStrategy()) == hash(bytecode.source_instructions[0][1])
+ assert 0 == len(g.traversal_strategies.traversal_strategies) # these strategies are proxies
+ ##
+ g = g.withStrategies(ReadOnlyStrategy(), IncidentToAdjacentStrategy())
+ bytecode = g.bytecode
+ assert 1 == len(bytecode.source_instructions)
+ assert 3 == len(bytecode.source_instructions[0])
+ assert "withStrategies" == bytecode.source_instructions[0][0]
+ assert ReadOnlyStrategy() == bytecode.source_instructions[0][1]
+ assert IncidentToAdjacentStrategy() == bytecode.source_instructions[0][2]
+ ##
+ bytecode = g.V().bytecode
+ assert 1 == len(bytecode.source_instructions)
+ assert 3 == len(bytecode.source_instructions[0])
+ assert "withStrategies" == bytecode.source_instructions[0][0]
+ assert ReadOnlyStrategy() == bytecode.source_instructions[0][1]
+ assert IncidentToAdjacentStrategy() == bytecode.source_instructions[0][2]
+ assert 1 == len(bytecode.step_instructions)
+ assert "V" == bytecode.step_instructions[0][0]
+ ##
+ bytecode = g.withoutStrategies(ReadOnlyStrategy()).V().bytecode
+ assert 2 == len(bytecode.source_instructions)
+ assert 3 == len(bytecode.source_instructions[0])
+ assert 2 == len(bytecode.source_instructions[1])
+ assert "withStrategies" == bytecode.source_instructions[0][0]
+ assert ReadOnlyStrategy() == bytecode.source_instructions[0][1]
+ assert IncidentToAdjacentStrategy() == bytecode.source_instructions[0][2]
+ assert "withoutStrategies" == bytecode.source_instructions[1][0]
+ assert ReadOnlyStrategy() == bytecode.source_instructions[1][1]
+ assert 1 == len(bytecode.step_instructions)
+ assert "V" == bytecode.step_instructions[0][0]
+ ##
+ bytecode = g.withoutStrategies(ReadOnlyStrategy(), LazyBarrierStrategy()).V().bytecode
+ assert 2 == len(bytecode.source_instructions)
+ assert 3 == len(bytecode.source_instructions[0])
+ assert 3 == len(bytecode.source_instructions[1])
+ assert "withStrategies" == bytecode.source_instructions[0][0]
+ assert ReadOnlyStrategy() == bytecode.source_instructions[0][1]
+ assert IncidentToAdjacentStrategy() == bytecode.source_instructions[0][2]
+ assert "withoutStrategies" == bytecode.source_instructions[1][0]
+ assert ReadOnlyStrategy() == bytecode.source_instructions[1][1]
+ assert LazyBarrierStrategy() == bytecode.source_instructions[1][2]
+ assert 1 == len(bytecode.step_instructions)
+ assert "V" == bytecode.step_instructions[0][0]
+
+ def test_configurable(self):
+ g = Graph().traversal()
+ bytecode = g.withStrategies(MatchAlgorithmStrategy("greedy")).bytecode
+ assert 1 == len(bytecode.source_instructions)
+ assert 2 == len(bytecode.source_instructions[0])
+ assert "withStrategies" == bytecode.source_instructions[0][0]
+ assert MatchAlgorithmStrategy() == bytecode.source_instructions[0][1]
+ assert "MatchAlgorithmStrategy" == str(bytecode.source_instructions[0][1])
+ assert hash(MatchAlgorithmStrategy()) == hash(
+ bytecode.source_instructions[0][1]) # even though different confs, same strategy
+ assert 0 == len(g.traversal_strategies.traversal_strategies) # these strategies are proxies
+ ###
+ bytecode = g.withStrategies(SubgraphStrategy(vertices=__.has("name","marko"))).bytecode
+ assert 1 == len(bytecode.source_instructions)
+ assert 2 == len(bytecode.source_instructions[0])
+ assert "withStrategies" == bytecode.source_instructions[0][0]
+ assert SubgraphStrategy() == bytecode.source_instructions[0][1]
+ strategy = bytecode.source_instructions[0][1]
+ assert 1 == len(strategy.configuration)
+ assert __.has("name","marko") == strategy.configuration["vertices"]
+
+if __name__ == '__main__':
+ unittest.main()
http://git-wip-us.apache.org/repos/asf/tinkerpop/blob/f84b1963/gremlin-python/src/main/jython/tests/structure/io/test_graphson.py
----------------------------------------------------------------------
diff --git a/gremlin-python/src/main/jython/tests/structure/io/test_graphson.py b/gremlin-python/src/main/jython/tests/structure/io/test_graphson.py
index 99c9a45..615a0e2 100644
--- a/gremlin-python/src/main/jython/tests/structure/io/test_graphson.py
+++ b/gremlin-python/src/main/jython/tests/structure/io/test_graphson.py
@@ -25,12 +25,14 @@ from unittest import TestCase
import six
-from gremlin_python.statics import long
+from gremlin_python.statics import *
from gremlin_python.structure.graph import Vertex
from gremlin_python.structure.graph import Path
from gremlin_python.structure.io.graphson import GraphSONReader
from gremlin_python.structure.io.graphson import GraphSONWriter
from gremlin_python.process.traversal import P
+from gremlin_python.process.strategies import SubgraphStrategy
+from gremlin_python.process.graph_traversal import __
class TestGraphSONReader(TestCase):
@@ -89,15 +91,22 @@ class TestGraphSONReader(TestCase):
class TestGraphSONWriter(TestCase):
def test_numbers(self):
- assert {"@type":"g:Int64","@value":2} == json.loads(GraphSONWriter.writeObject(long(2)))
- assert {"@type":"g:Int32","@value":1} == json.loads(GraphSONWriter.writeObject(1))
- assert {"@type":"g:Float","@value":3.2} == json.loads(GraphSONWriter.writeObject(3.2))
+ assert {"@type": "g:Int64", "@value": 2} == json.loads(GraphSONWriter.writeObject(long(2)))
+ assert {"@type": "g:Int32", "@value": 1} == json.loads(GraphSONWriter.writeObject(1))
+ assert {"@type": "g:Float", "@value": 3.2} == json.loads(GraphSONWriter.writeObject(3.2))
assert """true""" == GraphSONWriter.writeObject(True)
def test_P(self):
assert """{"@type":"g:P","@value":{"predicate":"and","value":[{"@type":"g:P","@value":{"predicate":"or","value":[{"@type":"g:P","@value":{"predicate":"lt","value":"b"}},{"@type":"g:P","@value":{"predicate":"gt","value":"c"}}]}},{"@type":"g:P","@value":{"predicate":"neq","value":"d"}}]}}""" == GraphSONWriter.writeObject(
P.lt("b").or_(P.gt("c")).and_(P.neq("d")))
+ def test_strategies(self):
+ # we have a proxy model for now given that we don't want to have to have g:XXX all registered on the Gremlin traversal machine (yet)
+ assert {"@type": "g:SubgraphStrategy"} == json.loads(GraphSONWriter.writeObject(SubgraphStrategy))
+ assert {"@type": "g:SubgraphStrategy", "@value": {
+ "vertices": {"@type": "g:Bytecode", "@value": {"step": [["has", "name", "marko"]]}}}} == json.loads(
+ GraphSONWriter.writeObject(SubgraphStrategy(vertices=__.has("name", "marko"))))
+
if __name__ == '__main__':
unittest.main()