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)