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

Cole-Greer pushed a commit to branch GValueFollowupTP4
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git

commit 447b77a922230e4617c1b4bc34d5f4d2710bbc61
Author: Cole Greer <[email protected]>
AuthorDate: Thu Jun 4 17:43:18 2026 -0700

    Add nested-GValue guard across all GLVs
    
    Match the Java reference GValue, which forbids wrapping a GValue inside 
another
    GValue. Adds a fail-fast guard to the Python, .NET, and Go GValue 
constructors
    (JavaScript already includes it in its new implementation), each rejecting a
    nested GValue with the message "GValues cannot be nested", plus a unit test 
per
    GLV.
---
 gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GValue.cs          | 3 +++
 .../test/Gremlin.Net.UnitTest/Process/Traversal/GremlinLangTests.cs | 6 ++++++
 gremlin-go/driver/gValue.go                                         | 3 +++
 gremlin-go/driver/gValue_test.go                                    | 5 +++++
 gremlin-python/src/main/python/gremlin_python/process/traversal.py  | 2 ++
 .../src/main/python/tests/unit/process/test_gremlin_lang.py         | 6 ++++++
 6 files changed, 25 insertions(+)

diff --git a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GValue.cs 
b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GValue.cs
index 97039fb229..71505fe94b 100644
--- a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GValue.cs
+++ b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/GValue.cs
@@ -58,6 +58,9 @@ namespace Gremlin.Net.Process.Traversal
         /// <exception cref="ArgumentException">Thrown when <paramref 
name="name" /> is not a valid identifier.</exception>
         public GValue(string name, T value)
         {
+            if (value is IGValue)
+                throw new ArgumentException("GValues cannot be nested");
+
             if (name == null)
                 throw new ArgumentNullException(nameof(name), "The parameter 
name cannot be null.");
 
diff --git 
a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Traversal/GremlinLangTests.cs
 
b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Traversal/GremlinLangTests.cs
index f7d4c5ee61..00f27abffc 100644
--- 
a/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Traversal/GremlinLangTests.cs
+++ 
b/gremlin-dotnet/test/Gremlin.Net.UnitTest/Process/Traversal/GremlinLangTests.cs
@@ -976,6 +976,12 @@ namespace Gremlin.Net.UnitTest.Process.Traversal
             Assert.Throws<ArgumentException>(() => new GValue<int>("_1", 1));
         }
 
+        [Fact]
+        public void GValue_nested_throws_ArgumentException()
+        {
+            Assert.Throws<ArgumentException>(() => new GValue<object>("x", new 
GValue<int>("y", 1)));
+        }
+
         [Fact]
         public void 
GValue_duplicate_name_different_value_throws_ArgumentException()
         {
diff --git a/gremlin-go/driver/gValue.go b/gremlin-go/driver/gValue.go
index 32b260da98..79d3fa5d16 100644
--- a/gremlin-go/driver/gValue.go
+++ b/gremlin-go/driver/gValue.go
@@ -34,6 +34,9 @@ type GValue struct {
 // NewGValue creates a new GValue to be used in traversals. The name must be 
non-empty, start with a
 // Unicode letter, and contain only Unicode letters, digits, or '_'. It cannot 
begin with "_".
 func NewGValue(name string, value interface{}) GValue {
+       if _, ok := value.(GValue); ok {
+               panic("GValues cannot be nested")
+       }
        runes := []rune(name)
        if len(runes) > 0 && runes[0] == '_' {
                panic(fmt.Sprintf("invalid GValue name '%v'. Should not start 
with _.", name))
diff --git a/gremlin-go/driver/gValue_test.go b/gremlin-go/driver/gValue_test.go
index 4f93f981b2..5c0fddfa75 100644
--- a/gremlin-go/driver/gValue_test.go
+++ b/gremlin-go/driver/gValue_test.go
@@ -112,6 +112,11 @@ func TestGValue(t *testing.T) {
                assert.NotPanics(t, func() { NewGValue("for", 1) })
        })
 
+       t.Run("test nested GValue rejected", func(t *testing.T) {
+               assert.Panics(t, func() { NewGValue("x", NewGValue("y", 1)) },
+                       "GValues cannot be nested")
+       })
+
        t.Run("test distinct but equal slices allowed under same name", func(t 
*testing.T) {
                g := NewGraphTraversalSource(nil, nil)
                param1 := NewGValue("ids", []int{1, 2, 3})
diff --git a/gremlin-python/src/main/python/gremlin_python/process/traversal.py 
b/gremlin-python/src/main/python/gremlin_python/process/traversal.py
index e575f1e572..7264307d4e 100644
--- a/gremlin-python/src/main/python/gremlin_python/process/traversal.py
+++ b/gremlin-python/src/main/python/gremlin_python/process/traversal.py
@@ -1158,6 +1158,8 @@ class GremlinLang(object):
 
 class GValue:
     def __init__(self, name, value):
+        if isinstance(value, GValue):
+            raise Exception('GValues cannot be nested')
         if not name or not name[0].isalpha() or not all(c.isalnum() or c == 
'_' for c in name[1:]):
             raise Exception(f'invalid GValue name {name}.')
         self.name = name
diff --git 
a/gremlin-python/src/main/python/tests/unit/process/test_gremlin_lang.py 
b/gremlin-python/src/main/python/tests/unit/process/test_gremlin_lang.py
index b3e7f4f09c..473f0ad80f 100644
--- a/gremlin-python/src/main/python/tests/unit/process/test_gremlin_lang.py
+++ b/gremlin-python/src/main/python/tests/unit/process/test_gremlin_lang.py
@@ -570,6 +570,12 @@ class TestGremlinLang(object):
         assert repr(p) == 'x=1'
         assert str(p) == 'x=1'
 
+    def test_gvalue_cannot_be_nested(self):
+        try:
+            GValue('x', GValue('y', 1))
+        except Exception as ex:
+            assert str(ex) == 'GValues cannot be nested'
+
     def test_unsupported_type_throws(self):
         g = traversal().with_(None)
         import pytest

Reply via email to