Forbid 'in' operator on depset with --incompatible_depset_is_not_iterable
RELNOTES: None.
PiperOrigin-RevId: 159948522
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
index 0e03157..2274076 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/BinaryOperatorExpression.java
@@ -69,8 +69,18 @@
}
/** Implements the "in" operator. */
- private static boolean in(Object lval, Object rval, Location location) throws EvalException {
- if (rval instanceof SkylarkQueryable) {
+ private static boolean in(Object lval, Object rval, Location location, Environment env)
+ throws EvalException {
+ if (env.getSemantics().incompatibleDepsetIsNotIterable && rval instanceof SkylarkNestedSet) {
+ throw new EvalException(
+ location,
+ "argument of type '"
+ + EvalUtils.getDataTypeName(rval)
+ + "' is not iterable. "
+ + "in operator only works on lists, tuples, dicts and strings. "
+ + "Use --incompatible_depset_is_not_iterable=false to temporarily disable "
+ + "this check.");
+ } else if (rval instanceof SkylarkQueryable) {
return ((SkylarkQueryable) rval).containsKey(lval, location);
} else if (rval instanceof String) {
if (lval instanceof String) {
@@ -159,10 +169,10 @@
return compare(lval, rval, location) >= 0;
case IN:
- return in(lval, rval, location);
+ return in(lval, rval, location, env);
case NOT_IN:
- return !in(lval, rval, location);
+ return !in(lval, rval, location, env);
default:
throw new AssertionError("Unsupported binary operator: " + operator);
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
index e6224fa..4a1d6a3 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/SkylarkEvaluationTest.java
@@ -884,6 +884,7 @@
new SkylarkTest("--incompatible_depset_is_not_iterable=true")
.testIfErrorContains("not iterable", "list(depset(['a', 'b']))")
.testIfErrorContains("not iterable", "max(depset([1, 2, 3]))")
+ .testIfErrorContains("not iterable", "1 in depset([1, 2, 3])")
.testIfErrorContains("not iterable", "sorted(depset(['a', 'b']))")
.testIfErrorContains("not iterable", "tuple(depset(['a', 'b']))")
.testIfErrorContains("not iterable", "[x for x in depset()]")
@@ -895,6 +896,7 @@
new SkylarkTest("--incompatible_depset_is_not_iterable=false")
.testStatement("str(list(depset(['a', 'b'])))", "[\"a\", \"b\"]")
.testStatement("max(depset([1, 2, 3]))", 3)
+ .testStatement("1 in depset([1, 2, 3])", true)
.testStatement("str(sorted(depset(['b', 'a'])))", "[\"a\", \"b\"]")
.testStatement("str(tuple(depset(['a', 'b'])))", "(\"a\", \"b\")")
.testStatement("str([x for x in depset()])", "[]")