You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tinkerpop.apache.org by sp...@apache.org on 2020/03/31 17:37:38 UTC

[tinkerpop] branch master updated (8e95a3a -> 98f3178)

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

spmallette pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git.


    from 8e95a3a  Merge branch '3.4-dev'
     add d84bd83  TINKERPOP-2350 Fixed bug in Traversal.clone() in gremlin-python
     add f92051a  Merge branch '3.3-dev' into 3.4-dev
     new 98f3178  Merge branch '3.4-dev'

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:
 CHANGELOG.asciidoc                                 |  3 ++-
 gremlin-python/glv/GraphTraversalSource.template   |  3 ++-
 gremlin-python/glv/TraversalSource.template        | 16 +++++++++++++++-
 .../gremlin_python/process/graph_traversal.py      |  3 ++-
 .../python/gremlin_python/process/traversal.py     | 16 +++++++++++++++-
 .../main/python/tests/process/test_traversal.py    | 22 +++++++++++++++++++++-
 6 files changed, 57 insertions(+), 6 deletions(-)


[tinkerpop] 01/01: Merge branch '3.4-dev'

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

spmallette pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 98f3178ac0312620f53e69f002ab616fb7c8f886
Merge: 8e95a3a f92051a
Author: Stephen Mallette <sp...@genoprime.com>
AuthorDate: Tue Mar 31 13:29:12 2020 -0400

    Merge branch '3.4-dev'

 CHANGELOG.asciidoc                                 |  3 ++-
 gremlin-python/glv/GraphTraversalSource.template   |  3 ++-
 gremlin-python/glv/TraversalSource.template        | 16 +++++++++++++++-
 .../gremlin_python/process/graph_traversal.py      |  3 ++-
 .../python/gremlin_python/process/traversal.py     | 16 +++++++++++++++-
 .../main/python/tests/process/test_traversal.py    | 22 +++++++++++++++++++++-
 6 files changed, 57 insertions(+), 6 deletions(-)

diff --cc gremlin-python/src/main/python/gremlin_python/process/traversal.py
index 569dfca,0000000..161de69
mode 100644,000000..100644
--- a/gremlin-python/src/main/python/gremlin_python/process/traversal.py
+++ b/gremlin-python/src/main/python/gremlin_python/process/traversal.py
@@@ -1,699 -1,0 +1,713 @@@
 +#
 +# 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.
 +#
 +
++import copy
 +from aenum import Enum
 +from .. import statics
 +from ..statics import long
 +
- 
 +class Traversal(object):
 +    def __init__(self, graph, traversal_strategies, bytecode):
 +        self.graph = graph
 +        self.traversal_strategies = traversal_strategies
 +        self.bytecode = bytecode
 +        self.traversers = None
 +        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):
 +        if self.traversers is None:
 +            self.traversal_strategies.apply_strategies(self)
 +        if self.last_traverser is None:
 +            self.last_traverser = next(self.traversers)
 +        object = self.last_traverser.object
 +        self.last_traverser.bulk = self.last_traverser.bulk - 1
 +        if self.last_traverser.bulk <= 0:
 +            self.last_traverser = None
 +        return object
 +
 +    def toList(self):
 +        return list(iter(self))
 +
 +    def toSet(self):
 +        return set(iter(self))
 +
 +    def iterate(self):
 +        self.bytecode.add_step("none")
 +        while True:
 +            try: self.nextTraverser()
 +            except StopIteration: return self
 +
 +    def nextTraverser(self):
 +        if self.traversers is None:
 +            self.traversal_strategies.apply_strategies(self)
 +        if self.last_traverser is None:
 +            return next(self.traversers)
 +        else:
 +            temp = self.last_traverser
 +            self.last_traverser = None
 +            return temp
 +
 +    def hasNext(self):
 +        if self.traversers is None:
 +            self.traversal_strategies.apply_strategies(self)
 +        if self.last_traverser is None:
 +            try: self.last_traverser = next(self.traversers)
 +            except StopIteration: return False
 +        return not(self.last_traverser is None) and self.last_traverser.bulk > 0
 +
 +    def next(self, amount=None):
 +        if amount is None:
 +            return self.__next__()
 +        else:
 +            count = 0
 +            tempList = []
 +            while count < amount:
 +                count = count + 1
 +                try: temp = self.__next__()
 +                except StopIteration: return tempList
 +                tempList.append(temp)
 +            return tempList
 +
 +    def promise(self, cb=None):
 +        self.traversal_strategies.apply_async_strategies(self)
 +        future_traversal = self.remote_results
 +        future = type(future_traversal)()
 +        def process(f):
 +            try:
 +                traversal = f.result()
 +            except Exception as e:
 +                future.set_exception(e)
 +            else:
 +                self.traversers = iter(traversal.traversers)
 +                if cb:
 +                    try:
 +                        result = cb(self)
 +                    except Exception as e:
 +                        future.set_exception(e)
 +                    else:
 +                        future.set_result(result)
 +                else:
 +                    future.set_result(self)
 +        future_traversal.add_done_callback(process)
 +        return future
 +
 +
 +Barrier = Enum('Barrier', ' normSack')
 +
 +statics.add_static('normSack', Barrier.normSack)
 +
 +Cardinality = Enum('Cardinality', ' list_ set_ single')
 +
 +statics.add_static('single', Cardinality.single)
 +statics.add_static('list_', Cardinality.list_)
 +statics.add_static('set_', Cardinality.set_)
 +
 +Column = Enum('Column', ' keys values')
 +
 +statics.add_static('keys', Column.keys)
 +statics.add_static('values', Column.values)
 +
 +Direction = Enum('Direction', ' BOTH IN OUT')
 +
 +statics.add_static('OUT', Direction.OUT)
 +statics.add_static('IN', Direction.IN)
 +statics.add_static('BOTH', Direction.BOTH)
 +
 +GraphSONVersion = Enum('GraphSONVersion', ' V1_0 V2_0 V3_0')
 +
 +statics.add_static('V1_0', GraphSONVersion.V1_0)
 +statics.add_static('V2_0', GraphSONVersion.V2_0)
 +statics.add_static('V3_0', GraphSONVersion.V3_0)
 +
 +GryoVersion = Enum('GryoVersion', ' V1_0 V3_0')
 +
 +statics.add_static('V1_0', GryoVersion.V1_0)
 +statics.add_static('V3_0', GryoVersion.V3_0)
 +
 +Order = Enum('Order', ' asc desc shuffle')
 +
 +statics.add_static('shuffle', Order.shuffle)
 +statics.add_static('asc', Order.asc)
 +statics.add_static('desc', Order.desc)
 +
 +Pick = Enum('Pick', ' any none')
 +
 +statics.add_static('any', Pick.any)
 +statics.add_static('none', Pick.none)
 +
 +Pop = Enum('Pop', ' all_ first last mixed')
 +
 +statics.add_static('first', Pop.first)
 +statics.add_static('last', Pop.last)
 +statics.add_static('all_', Pop.all_)
 +statics.add_static('mixed', Pop.mixed)
 +
 +Scope = Enum('Scope', ' global_ local')
 +
 +statics.add_static('global_', Scope.global_)
 +statics.add_static('local', Scope.local)
 +
 +
 +T = Enum('T', ' id id_ key label value')
 +
 +statics.add_static('id', T.id)
 +statics.add_static('label', T.label)
 +statics.add_static('id_', T.id_)
 +statics.add_static('key', T.key)
 +statics.add_static('value', T.value)
 +
 +
 +Operator = Enum('Operator', ' addAll and_ assign div max max_ min min_ minus mult or_ sum sum_ sumLong')
 +
 +statics.add_static('sum_', Operator.sum_)
 +statics.add_static('sum', Operator.sum_)
 +statics.add_static('minus', Operator.minus)
 +statics.add_static('mult', Operator.mult)
 +statics.add_static('div', Operator.div)
 +statics.add_static('min', Operator.min_)
 +statics.add_static('min_', Operator.min_)
 +statics.add_static('max_', Operator.max_)
 +statics.add_static('assign', Operator.assign)
 +statics.add_static('and_', Operator.and_)
 +statics.add_static('or_', Operator.or_)
 +statics.add_static('addAll', Operator.addAll)
 +statics.add_static('sumLong', Operator.sumLong)
 +
 +
 +class P(object):
 +    def __init__(self, operator, value, other=None):
 +        self.operator = operator
 +        self.value = value
 +        self.other = other
 +
 +    @staticmethod
 +    def between(*args):
 +        return P("between", *args)
 +
 +    @staticmethod
 +    def eq(*args):
 +        return P("eq", *args)
 +
 +    @staticmethod
 +    def gt(*args):
 +        return P("gt", *args)
 +
 +    @staticmethod
 +    def gte(*args):
 +        return P("gte", *args)
 +
 +    @staticmethod
 +    def inside(*args):
 +        return P("inside", *args)
 +
 +    @staticmethod
 +    def lt(*args):
 +        return P("lt", *args)
 +
 +    @staticmethod
 +    def lte(*args):
 +        return P("lte", *args)
 +
 +    @staticmethod
 +    def neq(*args):
 +        return P("neq", *args)
 +
 +    @staticmethod
 +    def not_(*args):
 +        return P("not", *args)
 +
 +    @staticmethod
 +    def outside(*args):
 +        return P("outside", *args)
 +
 +    @staticmethod
 +    def test(*args):
 +        return P("test", *args)
 +
 +    @staticmethod
 +    def within(*args):
 +        if len(args) == 1 and type(args[0]) == list:
 +            return P("within", args[0])
 +        else:
 +            return P("within", list(args))
 +        
 +    @staticmethod
 +    def without(*args):
 +        if len(args) == 1 and type(args[0]) == list:
 +            return P("without", args[0])
 +        else:
 +            return P("without", list(args))
 +
 +    def and_(self, arg):
 +        return P("and", self, arg)
 +
 +    def or_(self, arg):
 +        return P("or", self, arg)
 +
 +    def __eq__(self, other):
 +        return isinstance(other, self.__class__) and self.operator == other.operator and self.value == other.value and self.other == other.other
 +
 +    def __repr__(self):
 +        return self.operator + "(" + str(self.value) + ")" if self.other is None else self.operator + "(" + str(self.value) + "," + str(self.other) + ")"
 +
 +
 +def between(*args):
 +    return P.between(*args)
 +
 +
 +def eq(*args):
 +    return P.eq(*args)
 +
 +
 +def gt(*args):
 +    return P.gt(*args)
 +
 +
 +def gte(*args):
 +    return P.gte(*args)
 +
 +
 +def inside(*args):
 +    return P.inside(*args)
 +
 +
 +def lt(*args):
 +    return P.lt(*args)
 +
 +
 +def lte(*args):
 +    return P.lte(*args)
 +
 +
 +def neq(*args):
 +    return P.neq(*args)
 +
 +
 +def not_(*args):
 +    return P.not_(*args)
 +
 +
 +def outside(*args):
 +    return P.outside(*args)
 +
 +
 +def test(*args):
 +    return P.test(*args)
 +
 +
 +def within(*args):
 +    return P.within(*args)
 +
 +
 +def without(*args):
 +    return P.without(*args)
 +
 +
 +statics.add_static('between', between)
 +
 +statics.add_static('eq', eq)
 +
 +statics.add_static('gt', gt)
 +
 +statics.add_static('gte', gte)
 +
 +statics.add_static('inside', inside)
 +
 +statics.add_static('lt', lt)
 +
 +statics.add_static('lte', lte)
 +
 +statics.add_static('neq', neq)
 +
 +statics.add_static('not_', not_)
 +
 +statics.add_static('outside', outside)
 +
 +statics.add_static('test', test)
 +
 +statics.add_static('within', within)
 +
 +statics.add_static('without', without)
 +
 +
 +class TextP(P):
 +    def __init__(self, operator, value, other=None):
 +        P.__init__(self, operator, value, other)
 +
 +    @staticmethod
 +    def containing(*args):
 +        return TextP("containing", *args)
 +
 +    @staticmethod
 +    def endingWith(*args):
 +        return TextP("endingWith", *args)
 +
 +    @staticmethod
 +    def notContaining(*args):
 +        return TextP("notContaining", *args)
 +
 +    @staticmethod
 +    def notEndingWith(*args):
 +        return TextP("notEndingWith", *args)
 +
 +    @staticmethod
 +    def notStartingWith(*args):
 +        return TextP("notStartingWith", *args)
 +
 +    @staticmethod
 +    def startingWith(*args):
 +        return TextP("startingWith", *args)
 +
 +    def __eq__(self, other):
 +        return isinstance(other, self.__class__) and self.operator == other.operator and self.value == other.value and self.other == other.other
 +
 +    def __repr__(self):
 +        return self.operator + "(" + str(self.value) + ")" if self.other is None else self.operator + "(" + str(self.value) + "," + str(self.other) + ")"
 +
 +
 +def containing(*args):
 +    return TextP.containing(*args)
 +
 +
 +def endingWith(*args):
 +    return TextP.endingWith(*args)
 +
 +
 +def notContaining(*args):
 +    return TextP.notContaining(*args)
 +
 +
 +def notEndingWith(*args):
 +    return TextP.notEndingWith(*args)
 +
 +
 +def notStartingWith(*args):
 +    return TextP.notStartingWith(*args)
 +
 +
 +def startingWith(*args):
 +    return TextP.startingWith(*args)
 +
 +
 +statics.add_static('containing', containing)
 +
 +statics.add_static('endingWith', endingWith)
 +
 +statics.add_static('notContaining', notContaining)
 +
 +statics.add_static('notEndingWith', notEndingWith)
 +
 +statics.add_static('notStartingWith', notStartingWith)
 +
 +statics.add_static('startingWith', startingWith)
 +
 +
 +
 +
 +'''
 +IO
 +'''
 +
 +
 +class IO(object):
 +
 +    graphml = "graphml"
 +
 +    graphson = "graphson"
 +
 +    gryo = "gryo"
 +
 +    reader = "~tinkerpop.io.reader"
 +
 +    registry = "~tinkerpop.io.registry"
 +
 +    writer = "~tinkerpop.io.writer"
 +
 +
 +'''
 +ConnectedComponent
 +'''
 +
 +
 +class ConnectedComponent(object):
 +
 +    component = "gremlin.connectedComponentVertexProgram.component"
 +
 +    edges = "~tinkerpop.connectedComponent.edges"
 +
 +    propertyName = "~tinkerpop.connectedComponent.propertyName"
 +
 +
 +'''
 +ShortestPath
 +'''
 +
 +
 +class ShortestPath(object):
 +
 +    distance = "~tinkerpop.shortestPath.distance"
 +
 +    edges = "~tinkerpop.shortestPath.edges"
 +
 +    includeEdges = "~tinkerpop.shortestPath.includeEdges"
 +
 +    maxDistance = "~tinkerpop.shortestPath.maxDistance"
 +
 +    target = "~tinkerpop.shortestPath.target"
 +
 +
 +'''
 +PageRank
 +'''
 +
 +
 +class PageRank(object):
 +
 +    edges = "~tinkerpop.pageRank.edges"
 +
 +    propertyName = "~tinkerpop.pageRank.propertyName"
 +
 +    times = "~tinkerpop.pageRank.times"
 +
 +
 +'''
 +PeerPressure
 +'''
 +
 +
 +class PeerPressure(object):
 +
 +    edges = "~tinkerpop.peerPressure.edges"
 +
 +    propertyName = "~tinkerpop.peerPressure.propertyName"
 +
 +    times = "~tinkerpop.peerPressure.times"
 +
 +
 +'''
 +TRAVERSER
 +'''
 +
 +
 +class Traverser(object):
 +    def __init__(self, object, bulk=None):
 +        if bulk is None:
 +            bulk = long(1)
 +        self.object = object
 +        self.bulk = bulk
 +
 +    def __repr__(self):
 +        return str(self.object)
 +
 +    def __eq__(self, other):
 +        return isinstance(other, self.__class__) and self.object == other.object
 +
 +
 +'''
 +TRAVERSAL STRATEGIES
 +'''
 +
 +
 +class TraversalStrategies(object):
 +    global_cache = {}
 +
 +    def __init__(self, traversal_strategies=None):
 +        self.traversal_strategies =             traversal_strategies.traversal_strategies if traversal_strategies is not None else []
 +
 +    def add_strategies(self, traversal_strategies):
 +        self.traversal_strategies = self.traversal_strategies + traversal_strategies
 +
 +    def apply_strategies(self, traversal):
 +        for traversal_strategy in self.traversal_strategies:
 +            traversal_strategy.apply(traversal)
 +
 +    def apply_async_strategies(self, traversal):
 +        for traversal_strategy in self.traversal_strategies:
 +            traversal_strategy.apply_async(traversal)
 +
 +    def __repr__(self):
 +        return str(self.traversal_strategies)
 +
 +
 +class TraversalStrategy(object):
 +    def __init__(self, strategy_name=None, configuration=None, fqcn=None):
 +        self.fqcn = fqcn
 +        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 apply_async(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
 +'''
 +
 +
 +class Bytecode(object):
 +    def __init__(self, bytecode=None):
 +        self.source_instructions = []
 +        self.step_instructions = []
 +        self.bindings = {}
 +        if bytecode is not None:
 +            self.source_instructions = list(bytecode.source_instructions)
 +            self.step_instructions = list(bytecode.step_instructions)
 +
 +    def add_source(self, source_name, *args):
 +        instruction = [source_name]
 +        for arg in args:
 +            instruction.append(self.__convertArgument(arg))
 +        self.source_instructions.append(instruction)
 +
 +    def add_step(self, step_name, *args):
 +        instruction = [step_name]
 +        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 __copy__(self):
++        bb = Bytecode()
++        bb.source_instructions = self.source_instructions
++        bb.step_instructions = self.step_instructions
++        bb.bindings = self.bindings
++        return bb
++
++    def __deepcopy__(self, memo={}):
++        bb = Bytecode()
++        bb.source_instructions = copy.deepcopy(self.source_instructions, memo)
++        bb.step_instructions = copy.deepcopy(self.step_instructions, memo)
++        bb.bindings = copy.deepcopy(self.bindings, memo)
++        return bb
++
 +    def __convertArgument(self,arg):
 +        if isinstance(arg, Traversal):
 +            self.bindings.update(arg.bytecode.bindings)
 +            return arg.bytecode
 +        elif isinstance(arg, dict):
 +            newDict = {}
 +            for key in arg:
 +                newDict[self.__convertArgument(key)] = self.__convertArgument(arg[key])
 +            return newDict
 +        elif isinstance(arg, list):
 +            newList = []
 +            for item in arg:
 +                newList.append(self.__convertArgument(item))
 +            return newList
 +        elif isinstance(arg, set):
 +            newSet = set()
 +            for item in arg:
 +                newSet.add(self.__convertArgument(item))
 +            return newSet
 +        elif isinstance(arg, Binding):
 +            self.bindings[arg.key] = arg.value
 +            return Binding(arg.key, self.__convertArgument(arg.value))
 +        else:
 +            return arg
 +
 +    def __repr__(self):
 +        return (str(self.source_instructions) if len(self.source_instructions) > 0 else "") + \
 +               (str(self.step_instructions) if len(self.step_instructions) > 0 else "")
 +
 +
 +'''
 +BINDINGS
 +'''
 +
 +
 +class Bindings(object):
 +
 +    @staticmethod
 +    def of(key, value):
 +        if not isinstance(key, str):
 +            raise TypeError("Key must be str")
 +        return Binding(key, value)
 +
 +
 +class Binding(object):
 +    def __init__(self, key, value):
 +        self.key = key
 +        self.value = value
 +
 +    def __eq__(self, other):
 +        return isinstance(other, self.__class__) and self.key == other.key and self.value == other.value
 +
 +    def __hash__(self):
 +        return hash(self.key) + hash(self.value)
 +
 +    def __repr__(self):
 +        return "binding[" + self.key + "=" + str(self.value) + "]"
 +
 +
 +'''
 +WITH OPTIONS
 +'''
 +
 +
 +class WithOptions(object):
 +
 +    tokens = "~tinkerpop.valueMap.tokens"
 +
 +    none = 0
 +
 +    ids = 1
 +
 +    labels = 2
 +
 +    keys = 4
 +
 +    values = 8
 +
 +    all = 15
 +
 +    indexer = "~tinkerpop.index.indexer"
 +
 +    list = 0
 +
 +    map = 1
 +