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/12/18 18:04:46 UTC

[tinkerpop] branch master updated (1497704 -> 7685b54)

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 1497704  Merge branch '3.4-dev'
     add a9deecb  Fixed bug in Lambda translation for PythonTranslator. CTR
     new 7685b54  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                                         |  2 +-
 docs/src/reference/the-traversal.asciidoc                  |  3 ++-
 .../process/traversal/translator/PythonTranslator.java     |  3 ++-
 .../process/traversal/translator/PythonTranslatorTest.java | 14 +++++++-------
 4 files changed, 12 insertions(+), 10 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 7685b54456d7481db8160d587ed99dfc68ba2d6a
Merge: 1497704 a9deecb
Author: Stephen Mallette <st...@amazon.com>
AuthorDate: Fri Dec 18 13:04:20 2020 -0500

    Merge branch '3.4-dev'

 CHANGELOG.asciidoc                                         |  2 +-
 docs/src/reference/the-traversal.asciidoc                  |  3 ++-
 .../process/traversal/translator/PythonTranslator.java     |  3 ++-
 .../process/traversal/translator/PythonTranslatorTest.java | 14 +++++++-------
 4 files changed, 12 insertions(+), 10 deletions(-)

diff --cc gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/PythonTranslator.java
index 9b5f3b5,3e15bf1..ca1d28a
--- a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/PythonTranslator.java
+++ b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/translator/PythonTranslator.java
@@@ -19,11 -19,13 +19,12 @@@
  
  package org.apache.tinkerpop.gremlin.process.traversal.translator;
  
 -import org.apache.commons.configuration.ConfigurationConverter;
 -import org.apache.commons.lang.StringEscapeUtils;
 -import org.apache.commons.lang3.StringUtils;
 +import org.apache.commons.configuration2.ConfigurationConverter;
++import org.apache.commons.text.StringEscapeUtils;
  import org.apache.tinkerpop.gremlin.process.traversal.Bytecode;
 -import org.apache.tinkerpop.gremlin.process.traversal.Operator;
  import org.apache.tinkerpop.gremlin.process.traversal.P;
  import org.apache.tinkerpop.gremlin.process.traversal.SackFunctions;
 +import org.apache.tinkerpop.gremlin.process.traversal.Script;
  import org.apache.tinkerpop.gremlin.process.traversal.TextP;
  import org.apache.tinkerpop.gremlin.process.traversal.Translator;
  import org.apache.tinkerpop.gremlin.process.traversal.Traversal;
@@@ -118,227 -110,165 +119,227 @@@ public final class PythonTranslator imp
  
      ///////
  
 -    private String internalTranslate(final String start, final Bytecode bytecode) {
 -        final StringBuilder traversalScript = new StringBuilder(start);
 -        for (final Bytecode.Instruction instruction : bytecode.getInstructions()) {
 -            final String methodName = instruction.getOperator();
 -            final Object[] arguments = instruction.getArguments();
 -            if (0 == arguments.length)
 -                traversalScript.append(".").append(resolveSymbol(methodName)).append("()");
 -            else if (methodName.equals("range") && 2 == arguments.length)
 -                if (((Number) arguments[0]).longValue() + 1 == ((Number) arguments[1]).longValue())
 -                    traversalScript.append("[").append(arguments[0]).append("]");
 -                else
 -                    traversalScript.append("[").append(arguments[0]).append(":").append(arguments[1]).append("]");
 -            else if (methodName.equals("limit") && 1 == arguments.length)
 -                traversalScript.append("[0:").append(arguments[0]).append("]");
 -            else if (methodName.equals("values") && 1 == arguments.length && traversalScript.length() > 3 && !STEP_NAMES.contains(arguments[0].toString()))
 -                traversalScript.append(".").append(arguments[0]);
 -            else {
 -                traversalScript.append(".");
 -                String temp = resolveSymbol(methodName) + "(";
 +    /**
 +     * Performs standard type translation for the TinkerPop types to Python.
 +     */
 +    public static class DefaultTypeTranslator extends AbstractTypeTranslator {
  
 -                // jython has trouble with java varargs...wrapping in collection seems to solve the problem
 -                final boolean varargsBeware = instruction.getOperator().equals(TraversalSource.Symbols.withStrategies)
 -                        || instruction.getOperator().equals(TraversalSource.Symbols.withoutStrategies);
 -                if (varargsBeware) temp = temp + "[";
 +        public DefaultTypeTranslator(final boolean withParameters) {
 +            super(withParameters);
 +        }
  
 -                for (final Object object : arguments) {
 -                    temp = temp + convertToString(object) + ",";
 -                }
 -                temp = temp.substring(0, temp.length() - 1);
 +        @Override
 +        protected String getNullSyntax() {
 +            return "None";
 +        }
  
 -                if (varargsBeware) temp = temp + "]";
 +        @Override
 +        protected String getSyntax(final String o) {
 +            return o.contains("'") || o.contains(System.lineSeparator()) ?
 +                    "\"\"\"" + o + "\"\"\"" : "'" + o + "'";
 +        }
  
 -                traversalScript.append(temp).append(")");
 -            }
 -            // clip off __.
 -            if (this.importStatics && traversalScript.substring(0, 3).startsWith("__.")
 -                    && !NO_STATIC.stream().filter(name -> traversalScript.substring(3).startsWith(resolveSymbol(name))).findAny().isPresent()) {
 -                traversalScript.delete(0, 3);
 -            }
 +        @Override
 +        protected String getSyntax(final Boolean o) {
 +            return o ? "True" : "False";
          }
 -        return traversalScript.toString();
 -    }
  
 -    protected String convertToString(final Object object) {
 -        if (object instanceof Bytecode.Binding)
 -            return ((Bytecode.Binding) object).variable();
 -        else if (object instanceof Bytecode)
 -            return this.internalTranslate("__", (Bytecode) object);
 -        else if (object instanceof Traversal)
 -            return convertToString(((Traversal) object).asAdmin().getBytecode());
 -        else if (object instanceof String)
 -            return ((String) object).contains("'") || ((String) object).contains(System.lineSeparator()) ?
 -                    "\"\"\"" + object + "\"\"\"" : "'" + object + "'";
 -        else if (object instanceof Set) {
 -            final Set<String> set = new LinkedHashSet<>(((Set) object).size());
 -            for (final Object item : (Set) object) {
 -                set.add(convertToString(item));
 -            }
 -            return "set(" + set.toString() + ")";
 -        } else if (object instanceof List) {
 -            final List<String> list = new ArrayList<>(((List) object).size());
 -            for (final Object item : (List) object) {
 -                list.add(convertToString(item));
 +        @Override
 +        protected String getSyntax(final Date o) {
 +            return "datetime.datetime.utcfromtimestamp(" + o.getTime() + " / 1000.0)";
 +        }
 +
 +        @Override
 +        protected String getSyntax(final Timestamp o) {
 +            return "timestamp(" + o.getTime() + " / 1000.0)";
 +        }
 +
 +        @Override
 +        protected String getSyntax(final UUID o) {
 +            return "UUID('" + o.toString() +"')";
 +        }
 +
 +        @Override
 +        protected String getSyntax(final Lambda o) {
 +            final String lambdaString = o.getLambdaScript().trim();
-             return lambdaString.startsWith("lambda") ? lambdaString : "lambda " + lambdaString;
++            return "lambda: \"" + StringEscapeUtils.escapeJava(lambdaString) + "\"";
 +        }
 +
 +        @Override
 +        protected String getSyntax(final Number o) {
 +            // todo: nan/inf
 +            // all int/short/BigInteger/long are just python int/bignum
 +            if (o instanceof Double || o instanceof Float || o instanceof BigDecimal)
 +                return "float(" + o + ")";
 +            else if (o instanceof Byte)
 +                return "SingleByte(" + o + ")";
 +            else
 +                return o.toString();
 +        }
 +
 +        @Override
 +        protected String getSyntax(final SackFunctions.Barrier o) {
 +            return "Barrier." + resolveSymbol(o.toString());
 +        }
 +
 +        @Override
 +        protected String getSyntax(final VertexProperty.Cardinality o) {
 +            return "Cardinality." + resolveSymbol(o.toString());
 +        }
 +
 +        @Override
 +        protected String getSyntax(final TraversalOptionParent.Pick o) {
 +            return "Pick." + resolveSymbol(o.toString());
 +        }
 +
 +        @Override
 +        protected Script produceScript(final Set<?> o) {
 +            final Iterator<?> iterator = o.iterator();
 +            script.append("set(");
 +            while(iterator.hasNext()) {
 +                convertToScript(iterator.next());
 +                if (iterator.hasNext())
 +                    script.append(",");
              }
 -            return list.toString();
 -        } else if (object instanceof Map) {
 -            final StringBuilder map = new StringBuilder("{");
 -            for (final Map.Entry<?, ?> entry : ((Map<?, ?>) object).entrySet()) {
 -                map.append(convertToString(entry.getKey())).
 -                        append(":").
 -                        append(convertToString(entry.getValue())).
 -                        append(",");
 +            return script.append(")");
 +        }
 +
 +        @Override
 +        protected Script produceScript(final List<?> o) {
 +            final Iterator<?> iterator = o.iterator();
 +            script.append("[");
 +            while(iterator.hasNext()) {
 +                convertToScript(iterator.next());
 +                if (iterator.hasNext())
 +                    script.append(",");
              }
 -            return map.length() > 1 ? map.substring(0, map.length() - 1) + "}" : map.append("}").toString();
 -        } else if (object instanceof Long)
 -            return object + "L";
 -        else if (object instanceof TraversalStrategyProxy) {
 -            return resolveTraversalStrategyProxy((TraversalStrategyProxy) object);
 -        } else if (object instanceof TraversalStrategy) {
 -            return convertToString(new TraversalStrategyProxy((TraversalStrategy) object));
 -        } else if (object instanceof Boolean)
 -            return object.equals(Boolean.TRUE) ? "True" : "False";
 -        else if (object instanceof Class)
 -            return ((Class) object).getCanonicalName();
 -        else if (object instanceof VertexProperty.Cardinality)
 -            return "Cardinality." + resolveSymbol(object.toString());
 -        else if (object instanceof SackFunctions.Barrier)
 -            return "Barrier." + resolveSymbol(object.toString());
 -        else if (object instanceof TraversalOptionParent.Pick)
 -            return "Pick." + resolveSymbol(object.toString());
 -        else if (object instanceof Enum)
 -            return convertStatic(((Enum) object).getDeclaringClass().getSimpleName() + ".") + resolveSymbol(object.toString());
 -        else if (object instanceof P)
 -            return convertPToString((P) object, new StringBuilder()).toString();
 -        else if (object instanceof Element) {
 -            if (object instanceof Vertex) {
 -                final Vertex vertex = (Vertex) object;
 -                return "Vertex(" + convertToString(vertex.id()) + "," + convertToString(vertex.label()) + ")";
 -            } else if (object instanceof Edge) {
 -                final Edge edge = (Edge) object;
 -                return "Edge(" + convertToString(edge.id()) + "," +
 -                        convertToString(edge.outVertex()) + "," +
 -                        convertToString(edge.label()) + "," +
 -                        convertToString(edge.inVertex()) + ")";
 -            } else {
 -                final VertexProperty vertexProperty = (VertexProperty) object;
 -                return "VertexProperty(" + convertToString(vertexProperty.id()) + "," +
 -                        convertToString(vertexProperty.label()) + "," +
 -                        convertToString(vertexProperty.value()) + ")";
 +            return script.append("]");
 +        }
 +
 +        @Override
 +        protected Script produceScript(final Map<?, ?> o) {
 +            script.append("{");
 +            final Iterator<? extends Map.Entry<?, ?>> itty = o.entrySet().iterator();
 +            while (itty.hasNext()) {
 +                final Map.Entry<?,?> entry = itty.next();
 +                convertToScript(entry.getKey()).append(":");
 +                convertToScript(entry.getValue());
 +                if (itty.hasNext())
 +                    script.append(",");
              }
 -        } else if (object instanceof Lambda)
 -            return convertLambdaToString((Lambda) object);
 -        else
 -            return null == object ? "None" : object.toString();
 -    }
 +            return script.append("}");
 +        }
  
 -    private String convertStatic(final String name) {
 -        return this.importStatics ? "" : name;
 -    }
 +        @Override
 +        protected Script produceScript(final Class<?> o) {
 +            return script.append("GremlinType(" + o.getCanonicalName() + ")");
 +        }
 +
 +        @Override
 +        protected Script produceScript(final Enum<?> o) {
 +            return script.append(o.getDeclaringClass().getSimpleName() + "." + resolveSymbol(o.toString()));
 +        }
 +
 +        @Override
 +        protected Script produceScript(final Vertex o) {
 +            script.append("Vertex(");
 +            convertToScript(o.id()).append(",");
 +            return convertToScript(o.label()).append(")");
 +        }
 +
 +        @Override
 +        protected Script produceScript(final Edge o) {
 +            script.append("Edge(");
 +            convertToScript(o.id()).append(",");
 +            convertToScript(o.outVertex()).append(",");
 +            convertToScript(o.label()).append(",");
 +            return convertToScript(o.inVertex()).append(")");
 +        }
 +
 +        @Override
 +        protected Script produceScript(final VertexProperty<?> o) {
 +            script.append("VertexProperty(");
 +            convertToScript(o.id()).append(",");
 +            convertToScript(o.label()).append(",");
 +            return convertToScript(o.value()).append(")");
 +        }
  
 -    private StringBuilder convertPToString(final P p, final StringBuilder current) {
 -        if (p instanceof TextP) return convertTextPToString((TextP) p, current);
 -        if (p instanceof ConnectiveP) {
 -            final List<P<?>> list = ((ConnectiveP) p).getPredicates();
 -            for (int i = 0; i < list.size(); i++) {
 -                convertPToString(list.get(i), current);
 -                if (i < list.size() - 1)
 -                    current.append(p instanceof OrP ? ".or_(" : ".and_(");
 +        @Override
 +        protected Script produceScript(final TraversalStrategyProxy<?> o) {
 +            if (o.getConfiguration().isEmpty())
 +                return script.append("TraversalStrategy('" + o.getStrategyClass().getSimpleName() + "', None, '" + o.getStrategyClass().getName() + "')");
 +            else {
 +                script.append("TraversalStrategy('").append(o.getStrategyClass().getSimpleName()).append("',");
 +                convertToScript(ConfigurationConverter.getMap(o.getConfiguration()));
 +                script.append(", '");
 +                script.append(o.getStrategyClass().getName());
 +                return script.append("')");
              }
 -            current.append(")");
 -        } else
 -            current.append(convertStatic("P.")).append(p.getBiPredicate().toString()).append("(").append(convertToString(p.getValue())).append(")");
 -        return current;
 -    }
 +        }
  
 -    private StringBuilder convertTextPToString(final TextP p, final StringBuilder current) {
 -        current.append(convertStatic("TextP.")).append(p.getBiPredicate().toString()).append("(").append(convertToString(p.getValue())).append(")");
 -        return current;
 -    }
 +        @Override
 +        protected Script produceScript(final String traversalSource, final Bytecode o) {
 +            script.append(traversalSource);
 +            for (final Bytecode.Instruction instruction : o.getInstructions()) {
 +                final String methodName = instruction.getOperator();
 +                final Object[] arguments = instruction.getArguments();
 +                if (0 == arguments.length)
 +                    script.append(".").append(resolveSymbol(methodName)).append("()");
 +                else if (methodName.equals("range") && 2 == arguments.length)
 +                    if (((Number) arguments[0]).longValue() + 1 == ((Number) arguments[1]).longValue())
 +                        script.append("[").append(arguments[0].toString()).append("]");
 +                    else
 +                        script.append("[").append(arguments[0].toString()).append(":").append(arguments[1].toString()).append("]");
 +                else if (methodName.equals("limit") && 1 == arguments.length)
 +                    script.append("[0:").append(arguments[0].toString()).append("]");
 +                else if (methodName.equals("values") && 1 == arguments.length && script.getScript().length() > 3 && !STEP_NAMES.contains(arguments[0].toString()))
 +                    script.append(".").append(arguments[0].toString());
 +                else {
 +                    script.append(".").append(resolveSymbol(methodName)).append("(");
  
 -    protected String convertLambdaToString(final Lambda lambda) {
 -        final String lambdaString = lambda.getLambdaScript().trim();
 -        if (lambda.getLambdaLanguage().equalsIgnoreCase("gremlin-python")) {
 -            return lambdaString.startsWith("lambda") ? lambdaString : "lambda: \"" + lambdaString + "\"";
 -        } else {
 -            // gremlin-groovy
 -            return "lambda: \"" + StringEscapeUtils.escapeJava(lambdaString) + "\"";
 +                    // python has trouble with java varargs...wrapping in collection seems to solve the problem
 +                    final boolean varargsBeware = instruction.getOperator().equals(TraversalSource.Symbols.withStrategies)
 +                            || instruction.getOperator().equals(TraversalSource.Symbols.withoutStrategies);
 +                    if (varargsBeware) script.append("*[");
 +
 +                    final Iterator<?> itty = Stream.of(arguments).iterator();
 +                    while (itty.hasNext()) {
 +                        convertToScript(itty.next());
 +                        if (itty.hasNext()) script.append(",");
 +                    }
 +
 +                    if (varargsBeware) script.append("]");
 +
 +                    script.append(")");
 +                }
 +            }
 +            return script;
          }
 -    }
  
 -    protected String resolveSymbol(final String methodName) {
 -        return SymbolHelper.toPython(methodName);
 -    }
 +        @Override
 +        protected Script produceScript(final P<?> p) {
 +            if (p instanceof TextP) {
 +                script.append("TextP.").append(resolveSymbol(p.getBiPredicate().toString())).append("(");
 +                convertToScript(p.getValue());
 +            } else if (p instanceof ConnectiveP) {
 +                final List<P<?>> list = ((ConnectiveP) p).getPredicates();
 +                for (int i = 0; i < list.size(); i++) {
 +                    produceScript(list.get(i));
 +                    if (i < list.size() - 1) {
 +                        script.append(p instanceof OrP ? ".or_(" : ".and_(");
 +                    }
 +                }
 +            } else {
 +                script.append("P.").append(resolveSymbol(p.getBiPredicate().toString())).append("(");
 +                convertToScript(p.getValue());
 +            }
 +            script.append(")");
 +            return script;
 +        }
  
 -    protected String resolveTraversalStrategyProxy(final TraversalStrategyProxy proxy) {
 -        if (proxy.getConfiguration().isEmpty())
 -            return "TraversalStrategy('" + proxy.getStrategyClass().getSimpleName() + "')";
 -        else
 -            return "TraversalStrategy('" + proxy.getStrategyClass().getSimpleName() + "'," + convertToString(ConfigurationConverter.getMap(proxy.getConfiguration())) + ")";
 +        protected String resolveSymbol(final String methodName) {
 +            return SymbolHelper.toPython(methodName);
 +        }
      }
  
      static final class SymbolHelper {
diff --cc gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/PythonTranslatorTest.java
index aebe27f,3ec6410..e89c2ed
--- a/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/PythonTranslatorTest.java
+++ b/gremlin-core/src/test/java/org/apache/tinkerpop/gremlin/process/traversal/translator/PythonTranslatorTest.java
@@@ -91,17 -91,32 +91,17 @@@ public class PythonTranslatorTest 
      }
  
      @Test
 -    public void shouldTranslatePythonLambdas() {
 -        final Bytecode bytecode = g.withSideEffect("lengthSum", 0).withSack(1)
 -                .V()
 -                .filter(Lambda.predicate("x : x.get().label() == 'person'"))
 -                .flatMap(Lambda.function("lambda x : x.get().vertices(Direction.OUT)"))
 -                .map(Lambda.<Traverser<Object>, Integer>function("lambda x : len(x.get().value('name'))"))
 -                .sideEffect(Lambda.consumer(" x : x.sideEffects(\"lengthSum\", x.sideEffects('lengthSum') + x.get())    "))
 -                .order().by(Lambda.comparator("  lambda: a,b : 0 if a == b else 1 if a > b else -1"))
 -                .sack(Lambda.biFunction("lambda: a,b : a + b"))
 -                .asAdmin().getBytecode();
 -        assertEquals("g.withSideEffect('lengthSum',0).withSack(1).V().filter(lambda: \"x : x.get().label() == 'person'\").flatMap(lambda: \"lambda x : x.get().vertices(Direction.OUT)\").map(lambda: \"lambda x : len(x.get().value('name'))\").sideEffect(lambda: \"x : x.sideEffects(\\\"lengthSum\\\", x.sideEffects('lengthSum') + x.get())\").order().by(lambda: \"lambda: a,b : 0 if a == b else 1 if a > b else -1\").sack(lambda: \"lambda: a,b : a + b\")",
 -                translator.translate(bytecode));
 -    }
 -
 -    @Test
 -    public void shouldTranslateGroovyLambdas() {
 +    public void shouldTranslateLambdas() {
          final Bytecode bytecode = g.withSideEffect("lengthSum", 0).withSack(1)
                  .V()
-                 .filter(Lambda.predicate("x : x.get().label() == 'person'"))
-                 .flatMap(Lambda.function("lambda x : x.get().vertices(Direction.OUT)"))
-                 .map(Lambda.<Traverser<Object>, Integer>function("lambda x : len(x.get().value('name'))"))
-                 .sideEffect(Lambda.consumer(" x : x.sideEffects(\"lengthSum\", x.sideEffects('lengthSum') + x.get())    "))
-                 .order().by(Lambda.comparator("  lambda a,b : 0 if a == b else 1 if a > b else -1"))
-                 .sack(Lambda.biFunction("lambda a,b : a + b"))
+                 .filter(Lambda.predicate("x -> x.get().label() == 'person'", "gremlin-groovy"))
+                 .flatMap(Lambda.function("it.get().vertices(Direction.OUT)", "gremlin-groovy"))
+                 .map(Lambda.<Traverser<Object>, Integer>function("x -> x : len(x.get().value('name'))", "gremlin-groovy"))
+                 .sideEffect(Lambda.consumer("x -> x.sideEffects(\"lengthSum\", x.sideEffects('lengthSum') + x.get())    ", "gremlin-groovy"))
+                 .order().by(Lambda.comparator("a,b -> a == b ? 0 : (a > b) ? 1 : -1)", "gremlin-groovy"))
+                 .sack(Lambda.biFunction("a,b -> a + b", "gremlin-groovy"))
                  .asAdmin().getBytecode();
-         assertEquals("g.withSideEffect('lengthSum',0).withSack(1).V().filter(lambda x : x.get().label() == 'person').flatMap(lambda x : x.get().vertices(Direction.OUT)).map(lambda x : len(x.get().value('name'))).sideEffect(lambda x : x.sideEffects(\"lengthSum\", x.sideEffects('lengthSum') + x.get())).order().by(lambda a,b : 0 if a == b else 1 if a > b else -1).sack(lambda a,b : a + b)",
+         assertEquals("g.withSideEffect('lengthSum',0).withSack(1).V().filter(lambda: \"x -> x.get().label() == 'person'\").flatMap(lambda: \"it.get().vertices(Direction.OUT)\").map(lambda: \"x -> x : len(x.get().value('name'))\").sideEffect(lambda: \"x -> x.sideEffects(\\\"lengthSum\\\", x.sideEffects('lengthSum') + x.get())\").order().by(lambda: \"a,b -> a == b ? 0 : (a > b) ? 1 : -1)\").sack(lambda: \"a,b -> a + b\")",
 -                translator.translate(bytecode));
 +                translator.translate(bytecode).getScript());
      }
  }