This is an automated email from the ASF dual-hosted git repository.
Cole-Greer pushed a commit to branch 3.7-dev
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
The following commit(s) were added to refs/heads/3.7-dev by this push:
new 5349dbb89d Deprecate ProductiveByStrategy (#3544)
5349dbb89d is described below
commit 5349dbb89d23b4b1b5c9ceca2a7c82e7dfbbb156
Author: Guian Gumpac <[email protected]>
AuthorDate: Wed Jul 22 16:32:47 2026 -0700
Deprecate ProductiveByStrategy (#3544)
Assisted-by: Kiro:claude-opus-4.8
---
CHANGELOG.asciidoc | 1 +
docs/src/upgrade/release-3.7.x.asciidoc | 9 +++++++++
.../traversal/strategy/optimization/ProductiveByStrategy.java | 3 +++
.../Traversal/Strategy/Optimization/ProductiveByStrategy.cs | 2 ++
gremlin-go/driver/strategies.go | 5 +++++
.../gremlin-javascript/lib/process/traversal-strategy.js | 4 ++++
.../src/main/python/gremlin_python/process/strategies.py | 5 +++++
7 files changed, 29 insertions(+)
diff --git a/CHANGELOG.asciidoc b/CHANGELOG.asciidoc
index e7bb8dd607..208cefd4a7 100644
--- a/CHANGELOG.asciidoc
+++ b/CHANGELOG.asciidoc
@@ -37,6 +37,7 @@
image::https://raw.githubusercontent.com/apache/tinkerpop/master/docs/static/ima
* Corrected numerous inaccuracies in the reference documentation, including
wrong default values (connection pool sizes, buffer sizes, ports, timeouts),
stale serializer class names, removed options documented as available, and
broken code examples across the JVM, Python, `.NET`, Go, and JavaScript drivers.
* Fixed a panic in `gremlin-go` `PartitionStrategy` when `ReadPartitions` was
left unset.
* Fixed `gremlin-python` `ProductiveByStrategy` to pass through the
`productiveKeys` argument, which was previously accepted but never serialized
to the server.
+* Deprecated `ProductiveByStrategy` which was introduced as a temporary way to
mimic pre-3.5.0 null processing behavior.
[[release-3-7-6]]
=== TinkerPop 3.7.6 (Release Date: April 1, 2026)
diff --git a/docs/src/upgrade/release-3.7.x.asciidoc
b/docs/src/upgrade/release-3.7.x.asciidoc
index d936905f95..4fa1a36cc7 100644
--- a/docs/src/upgrade/release-3.7.x.asciidoc
+++ b/docs/src/upgrade/release-3.7.x.asciidoc
@@ -110,6 +110,15 @@ example `g.V().hasId(1, 2, 4)`).
See: link:https://issues.apache.org/jira/browse/TINKERPOP-3273[TINKERPOP-3273]
+==== Deprecated ProductiveByStrategy
+
+`ProductiveByStrategy` is deprecated as of 3.7.7 and is not replaced. The
strategy was introduced in 3.5.0 as a
+temporary way to mimic the `null` processing behavior of versions prior to
3.5.0, where a `by()` modulator would
+always produce a result. That compatibility need has passed, so the strategy
is no longer recommended and will be
+removed in 4.0.0. This deprecation applies across all Gremlin Language
Variants.
+
+See: link:https://issues.apache.org/jira/browse/TINKERPOP-3042[TINKERPOP-3042]
+
== TinkerPop 3.7.6
*Release Date: April 1, 2026*
diff --git
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/ProductiveByStrategy.java
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/ProductiveByStrategy.java
index 271b02d32f..58e31b3708 100644
---
a/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/ProductiveByStrategy.java
+++
b/gremlin-core/src/main/java/org/apache/tinkerpop/gremlin/process/traversal/strategy/optimization/ProductiveByStrategy.java
@@ -51,7 +51,10 @@ import java.util.Set;
* {@link Traversal} argument or {@code null}. In this way, the {@code by()}
is always "productive". This strategy
* is an "optimization" but it is perhaps more of a "decoration", but it
should follow
* {@link ByModulatorOptimizationStrategy} which features optimizations
relevant to this one.
+ *
+ * @deprecated As of release 3.7.7, not replaced. This strategy was added as a
temporary way to mimic pre-3.5.0 null processing behavior.
*/
+@Deprecated
public class ProductiveByStrategy extends
AbstractTraversalStrategy<TraversalStrategy.OptimizationStrategy> implements
TraversalStrategy.OptimizationStrategy {
public static final String PRODUCTIVE_KEYS = "productiveKeys";
diff --git
a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Strategy/Optimization/ProductiveByStrategy.cs
b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Strategy/Optimization/ProductiveByStrategy.cs
index 59fb9be4bf..aa0fa35a2e 100644
---
a/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Strategy/Optimization/ProductiveByStrategy.cs
+++
b/gremlin-dotnet/src/Gremlin.Net/Process/Traversal/Strategy/Optimization/ProductiveByStrategy.cs
@@ -21,6 +21,7 @@
#endregion
+using System;
using System.Collections.Generic;
namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
@@ -28,6 +29,7 @@ namespace Gremlin.Net.Process.Traversal.Strategy.Optimization
/// <summary>
/// Ensures that all by() modulators end up producing a result with
null as the default.
/// </summary>
+ [Obsolete("Deprecated as of 3.7.7. Not replaced. This strategy was added
as a temporary way to mimic pre-3.5.0 null processing behavior.", false)]
public class ProductiveByStrategy : AbstractTraversalStrategy
{
private const string JavaFqcn = OptimizationNamespace +
nameof(ProductiveByStrategy);
diff --git a/gremlin-go/driver/strategies.go b/gremlin-go/driver/strategies.go
index 5998747d62..f03a00f01f 100644
--- a/gremlin-go/driver/strategies.go
+++ b/gremlin-go/driver/strategies.go
@@ -364,6 +364,9 @@ func PathRetractionStrategy() TraversalStrategy {
// the initial Traversal argument or null. In this way, the By() is always
"productive". This strategy
// is an "optimization" but it is perhaps more of a "decoration", but it
should follow
// ByModulatorOptimizationStrategy which features optimizations relevant to
this one.
+//
+// Deprecated: As of release 3.7.7, not replaced. This strategy was added as a
temporary way to mimic
+// pre-3.5.0 null processing behavior.
func ProductiveByStrategy(config ProductiveByStrategyConfig) TraversalStrategy
{
configMap := make(map[string]interface{})
configMap["productiveKeys"] = config.ProductiveKeys
@@ -373,6 +376,8 @@ func ProductiveByStrategy(config
ProductiveByStrategyConfig) TraversalStrategy {
// ProductiveByStrategyConfig provides configuration options for
ProductiveByStrategy.
// Zeroed (unset) values are used.
+//
+// Deprecated: As of release 3.7.7, not replaced.
type ProductiveByStrategyConfig struct {
ProductiveKeys []string
}
diff --git
a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal-strategy.js
b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal-strategy.js
index d041123497..f673d46d58 100644
---
a/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal-strategy.js
+++
b/gremlin-javascript/src/main/javascript/gremlin-javascript/lib/process/traversal-strategy.js
@@ -151,6 +151,10 @@ class SubgraphStrategy extends TraversalStrategy {
}
}
+/**
+ * @deprecated As of release 3.7.7, not replaced. This strategy was added as a
temporary way to mimic pre-3.5.0
+ * null processing behavior.
+ */
class ProductiveByStrategy extends TraversalStrategy {
/**
* @param {Object} [options]
diff --git
a/gremlin-python/src/main/python/gremlin_python/process/strategies.py
b/gremlin-python/src/main/python/gremlin_python/process/strategies.py
index 10deb6bb26..5ebbe98405 100644
--- a/gremlin-python/src/main/python/gremlin_python/process/strategies.py
+++ b/gremlin-python/src/main/python/gremlin_python/process/strategies.py
@@ -20,6 +20,7 @@
__author__ = 'Marko A. Rodriguez (http://markorodriguez.com)'
from gremlin_python.process.traversal import TraversalStrategy
+import warnings
base_namespace = 'org.apache.tinkerpop.gremlin.process.traversal.strategy.'
decoration_namespace = base_namespace + 'decoration.'
@@ -187,6 +188,10 @@ class PathRetractionStrategy(TraversalStrategy):
class ProductiveByStrategy(TraversalStrategy):
def __init__(self, productiveKeys=None):
+ warnings.warn(
+ "ProductiveByStrategy is deprecated as of 3.7.7, not replaced. It
was added as a temporary way to "
+ "mimic pre-3.5.0 null processing behavior.",
+ DeprecationWarning)
TraversalStrategy.__init__(self, fqcn=optimization_namespace +
'ProductiveByStrategy')
if productiveKeys is not None:
self.configuration["productiveKeys"] = productiveKeys