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

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

commit ea56e9857757b7d4b88ff7f8aec2e90cf35b8959
Author: Stephen Mallette <[email protected]>
AuthorDate: Thu Oct 15 16:23:32 2020 -0400

    TINKERPOP-2435 Ignored python magic methods in Gremlin sugar
    
    Seems like less of a problem in practice as most Python users wouldn't 
improperly do g.V().__len__ but debugging tools might do such things on code 
introspection as PyCharm does with its debugger. That of course would build 
unexpected Gremlin and will typically return no values (as any traversal ending 
with values() and a key that doesnt exist will just filter out).
---
 CHANGELOG.asciidoc                                     |  1 +
 gremlin-python/glv/GraphTraversalSource.template       |  3 +++
 .../jython/gremlin_python/process/graph_traversal.py   |  3 +++
 .../src/main/jython/tests/process/test_traversal.py    | 18 ++++++++++++++++++
 4 files changed, 25 insertions(+)

diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index 10f6c48..227195b 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -33,6 +33,7 @@ 
image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
 * Deprecated `withGraph()` in favor of `withEmbedded()` on 
`AnonymousTraversalSource`.
 * Added support for per-request level configurations, like timeouts, in .NET, 
Python and Javascript.
 * Fixed bug in Javascript `Translator` that wasn't handling child traversals 
well.
+* Prevented Gremlin Python sugar from being confused by Python magic methods.
 * Implemented `AutoCloseable` on `MultiIterator`.
 * Fixed an iterator leak in `HasContainer`.
 * Avoid creating unnecessary detached objects in JVM.
diff --git a/gremlin-python/glv/GraphTraversalSource.template 
b/gremlin-python/glv/GraphTraversalSource.template
index 323a360..7d6da68 100644
--- a/gremlin-python/glv/GraphTraversalSource.template
+++ b/gremlin-python/glv/GraphTraversalSource.template
@@ -99,6 +99,9 @@ class GraphTraversal(Traversal):
             raise TypeError("Index must be int or slice")
 
     def __getattr__(self, key):
+        if key.startswith('__'):
+            raise AttributeError(
+                f'Python magic methods or keys starting with double underscore 
cannot be used for Gremlin sugar - prefer values({key})')
         return self.values(key)
 
     def clone(self):
diff --git 
a/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py 
b/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
index b9a9847..c8247b5 100644
--- a/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
+++ b/gremlin-python/src/main/jython/gremlin_python/process/graph_traversal.py
@@ -149,6 +149,9 @@ class GraphTraversal(Traversal):
             raise TypeError("Index must be int or slice")
 
     def __getattr__(self, key):
+        if key.startswith('__'):
+            raise AttributeError(
+                f'Python magic methods or keys starting with double underscore 
cannot be used for Gremlin sugar - prefer values({key})')
         return self.values(key)
 
     def clone(self):
diff --git a/gremlin-python/src/main/jython/tests/process/test_traversal.py 
b/gremlin-python/src/main/jython/tests/process/test_traversal.py
index 5b9b619..f2c1682 100644
--- a/gremlin-python/src/main/jython/tests/process/test_traversal.py
+++ b/gremlin-python/src/main/jython/tests/process/test_traversal.py
@@ -19,6 +19,8 @@
 
 __author__ = 'Marko A. Rodriguez (http://markorodriguez.com)'
 
+from pytest import fail
+
 from gremlin_python.structure.graph import Graph
 from gremlin_python.process.anonymous_traversal import traversal
 from gremlin_python.process.traversal import P
@@ -104,4 +106,20 @@ class TestTraversal(object):
         assert 5 == len(clone.bytecode.step_instructions)
         assert 4 == len(cloneClone.bytecode.step_instructions)
 
+    def test_no_sugar_for_magic_methods(self):
+        g = traversal().withGraph(Graph())
+
+        t = g.V().age
+        assert 2 == len(t.bytecode.step_instructions)
+
+        try:
+            t = g.V().__len__
+            fail("can't do sugar with magic")
+        except AttributeError as err:
+            assert str(err) == 'Python magic methods or keys starting with 
double underscore cannot be used for Gremlin sugar - prefer values(__len__)'
+
+
+
+
+
 

Reply via email to