Allow lists to be modified while a For loop is iterating over them.
This does not affect the loop's iteration. Similar work is needed for
comprehension For clauses.
--
MOS_MIGRATED_REVID=128357769
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 73e5f1b..4ac19c4 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
@@ -296,6 +296,55 @@
}
@Test
+ public void testForUpdateList() throws Exception {
+ // Check that modifying the list within the loop doesn't affect what gets iterated over.
+ // TODO(brandjon): When we support in-place assignment to a list index, also test that
+ // as a modification here.
+ new SkylarkTest().setUp("def foo():",
+ " xs = ['a', 'b', 'c']",
+ " s = ''",
+ " for x in xs:",
+ " s = s + x",
+ " if x == 'a':",
+ " xs.pop(0)",
+ " xs.pop(1)",
+ " elif x == 'c':",
+ " xs.append('d')",
+ " return s",
+ "s = foo()").testLookup("s", "abc");
+ }
+
+ @Test
+ public void testForUpdateDict() throws Exception {
+ // Check that modifying the dict within the loop doesn't affect what gets iterated over.
+ new SkylarkTest().setUp("def foo():",
+ " d = {'a': 1, 'b': 2, 'c': 3}",
+ " s = ''",
+ " for k in d:",
+ " s = s + k",
+ " if k == 'a':",
+ " d.pop('a')",
+ " d.pop('b')",
+ " d.update({'d': 4})",
+ " return s",
+ "s = foo()").testLookup("s", "abc");
+ }
+
+ @Test
+ public void testForDeepUpdate() throws Exception {
+ // Check that indirectly reachable values can still be manipulated as normal.
+ new SkylarkTest().setUp("def foo():",
+ " xs = [['a'], ['b'], ['c']]",
+ " ys = []",
+ " for x in xs:",
+ " for y in x:",
+ " ys.append(y)",
+ " xs[2].append(x[0])",
+ " return ys",
+ "ys = foo()").testLookup("ys", MutableList.of(null, "a", "b", "c", "a", "b"));
+ }
+
+ @Test
public void testForNotIterable() throws Exception {
new SkylarkTest()
.update("mock", new Mock())