Introduce `--incompatible_disallow_slash_operator` to disable `/` operator.
RELNOTES:
The `/` operator is deprecated in favor of `//` (floor integer division).
Try the `--incompatible_disallow_slash_operator` flag to ensure your code
is forward-compatible.
PiperOrigin-RevId: 192430310
diff --git a/site/docs/skylark/backward-compatibility.md b/site/docs/skylark/backward-compatibility.md
index e5d8c75..801148b 100644
--- a/site/docs/skylark/backward-compatibility.md
+++ b/site/docs/skylark/backward-compatibility.md
@@ -98,9 +98,9 @@
deprecated:
``` python
-depset1 + depset2
-depset1 | depset2
-depset1.union(depset2)
+depset1 + depset2 # deprecated
+depset1 | depset2 # deprecated
+depset1.union(depset2) # deprecated
```
The recommended solution is to use the `depset` constructor:
@@ -148,6 +148,20 @@
* Default: `false`
+### Integer division operator is `//`
+
+Integer division operator is now `//` instead of `/`. This aligns with
+Python 3 and it highlights the fact it is a floor division.
+
+```python
+x = 7 / 2 # deprecated
+
+x = 7 // 2 # x is 3
+```
+
+* Flag: `--incompatible_disallow_slash_operator`
+* Default: `false`
+
### New actions API
This change removes the old methods for registering actions within rules, and
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsCodec.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsCodec.java
index c2fa734..19c346f 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsCodec.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsCodec.java
@@ -50,6 +50,7 @@
codedOut.writeBoolNoTag(semantics.incompatibleDisableObjcProviderResources());
codedOut.writeBoolNoTag(semantics.incompatibleDisallowDictPlus());
codedOut.writeBoolNoTag(semantics.incompatibleDisallowOldStyleArgsAdd());
+ codedOut.writeBoolNoTag(semantics.incompatibleDisallowSlashOperator());
codedOut.writeBoolNoTag(semantics.incompatibleDisallowToplevelIfStatement());
codedOut.writeBoolNoTag(semantics.incompatibleNewActionsApi());
codedOut.writeBoolNoTag(semantics.incompatiblePackageNameIsAFunction());
@@ -72,6 +73,7 @@
builder.incompatibleDisableObjcProviderResources(codedIn.readBool());
builder.incompatibleDisallowDictPlus(codedIn.readBool());
builder.incompatibleDisallowOldStyleArgsAdd(codedIn.readBool());
+ builder.incompatibleDisallowSlashOperator(codedIn.readBool());
builder.incompatibleDisallowToplevelIfStatement(codedIn.readBool());
builder.incompatibleNewActionsApi(codedIn.readBool());
builder.incompatiblePackageNameIsAFunction(codedIn.readBool());
diff --git a/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java b/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java
index 38ca1d0..facbbea 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/SkylarkSemanticsOptions.java
@@ -144,6 +144,19 @@
)
public boolean incompatibleDisallowDictPlus;
+ @Option(
+ name = "incompatible_disallow_slash_operator",
+ defaultValue = "false",
+ documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
+ effectTags = {OptionEffectTag.UNKNOWN},
+ metadataTags = {
+ OptionMetadataTag.INCOMPATIBLE_CHANGE,
+ OptionMetadataTag.TRIGGERED_BY_ALL_INCOMPATIBLE_CHANGES
+ },
+ help = "If set to true, the `/` operator is disabled. Use `//` for integer division."
+ )
+ public boolean incompatibleDisallowSlashOperator;
+
/** Controls legacy arguments to ctx.actions.Args#add. */
@Option(
name = "incompatible_disallow_old_style_args_add",
@@ -269,6 +282,7 @@
.incompatibleDisableObjcProviderResources(incompatibleDisableObjcProviderResources)
.incompatibleDisallowDictPlus(incompatibleDisallowDictPlus)
.incompatibleDisallowOldStyleArgsAdd(incompatibleDisallowOldStyleArgsAdd)
+ .incompatibleDisallowSlashOperator(incompatibleDisallowSlashOperator)
.incompatibleDisallowToplevelIfStatement(incompatibleDisallowToplevelIfStatement)
.incompatibleNewActionsApi(incompatibleNewActionsApi)
.incompatiblePackageNameIsAFunction(incompatiblePackageNameIsAFunction)
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 b1f835c..283fd57 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
@@ -205,6 +205,15 @@
return mult(lhs, rhs, env, location);
case DIVIDE:
+ if (env.getSemantics().incompatibleDisallowSlashOperator()) {
+ throw new EvalException(
+ location,
+ "The `/` operator has been removed. Please use the `//` operator for integer "
+ + "division. You can temporarily enable the `/` operator by passing "
+ + "the flag --incompatible_disallow_slash_operator=false");
+ }
+ return divide(lhs, rhs, location);
+
case FLOOR_DIVIDE:
return divide(lhs, rhs, location);
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java
index e0ef87f..b6665c4 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/SkylarkSemantics.java
@@ -53,6 +53,8 @@
public abstract boolean incompatibleDisallowOldStyleArgsAdd();
+ public abstract boolean incompatibleDisallowSlashOperator();
+
public abstract boolean incompatibleDisallowToplevelIfStatement();
public abstract boolean incompatibleNewActionsApi();
@@ -89,6 +91,7 @@
.incompatibleDisableObjcProviderResources(false)
.incompatibleDisallowDictPlus(false)
.incompatibleDisallowOldStyleArgsAdd(false)
+ .incompatibleDisallowSlashOperator(false)
.incompatibleDisallowToplevelIfStatement(true)
.incompatibleNewActionsApi(false)
.incompatiblePackageNameIsAFunction(false)
@@ -117,6 +120,8 @@
public abstract Builder incompatibleDisallowOldStyleArgsAdd(boolean value);
+ public abstract Builder incompatibleDisallowSlashOperator(boolean value);
+
public abstract Builder incompatibleDisallowToplevelIfStatement(boolean value);
public abstract Builder incompatibleNewActionsApi(boolean value);
diff --git a/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java b/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java
index 6c4a34e..9798394 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/SkylarkSemanticsConsistencyTest.java
@@ -126,6 +126,7 @@
"--incompatible_disable_objc_provider_resources=" + rand.nextBoolean(),
"--incompatible_disallow_dict_plus=" + rand.nextBoolean(),
"--incompatible_disallow_old_style_args_add=" + rand.nextBoolean(),
+ "--incompatible_disallow_slash_operator=" + rand.nextBoolean(),
"--incompatible_disallow_toplevel_if_statement=" + rand.nextBoolean(),
"--incompatible_new_actions_api=" + rand.nextBoolean(),
"--incompatible_package_name_is_a_function=" + rand.nextBoolean(),
@@ -149,6 +150,7 @@
.incompatibleDisableObjcProviderResources(rand.nextBoolean())
.incompatibleDisallowDictPlus(rand.nextBoolean())
.incompatibleDisallowOldStyleArgsAdd(rand.nextBoolean())
+ .incompatibleDisallowSlashOperator(rand.nextBoolean())
.incompatibleDisallowToplevelIfStatement(rand.nextBoolean())
.incompatibleNewActionsApi(rand.nextBoolean())
.incompatiblePackageNameIsAFunction(rand.nextBoolean())
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java b/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java
index c3c18a9..c0bd4a4 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/EvaluationTest.java
@@ -195,8 +195,14 @@
}
@Test
+ public void testSlashOperatorIsForbidden() throws Exception {
+ newTest("--incompatible_disallow_slash_operator=true")
+ .testIfErrorContains("The `/` operator has been removed.", "5 / 2");
+ }
+
+ @Test
public void testDivision() throws Exception {
- newTest()
+ newTest("--incompatible_disallow_slash_operator=false")
.testStatement("6 / 2", 3)
.testStatement("6 / 4", 1)
.testStatement("3 / 6", 0)