Skip to content

Commit dfa9c62

Browse files
tetrominocopybara-github
authored andcommitted
Allow dict() and dict.update() to take arbitrary maps, not necessarily dicts.
In particular, this allows immutable view objects returned by native.existing_rule/s() with --incompatible_existing_rules_immutable_view to be used in dict() and dict.update(). Partially addresses #13605 PiperOrigin-RevId: 478527510 Change-Id: Ic796df9d556027c5d797b03ca85aebf1c90165cd
1 parent cf99f84 commit dfa9c62

2 files changed

Lines changed: 49 additions & 3 deletions

File tree

‎src/main/java/net/starlark/java/eval/Dict.java‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -339,10 +339,10 @@ public void update(Object pairs, Dict<String, Object> kwargs, StarlarkThread thr
339339

340340
// Common implementation of dict(pairs, **kwargs) and dict.update(pairs, **kwargs).
341341
static void update(
342-
String funcname, Dict<Object, Object> dict, Object pairs, Dict<String, Object> kwargs)
342+
String funcname, Dict<Object, Object> dict, Object pairs, Map<String, Object> kwargs)
343343
throws EvalException {
344-
if (pairs instanceof Dict) { // common case
345-
dict.putEntries((Dict<?, ?>) pairs);
344+
if (pairs instanceof Map) { // common case
345+
dict.putEntries((Map<?, ?>) pairs);
346346
} else {
347347
Iterable<?> iterable;
348348
try {

‎src/test/java/com/google/devtools/build/lib/packages/NativeExistingRulesTest.java‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,52 @@ public void existingRule_returnsDictLikeObject() throws Exception {
336336
assertThat(getSaved("'invalid_attr' in r")).isEqualTo(false);
337337
}
338338

339+
@Test
340+
public void existingRule_asDictArgument() throws Exception {
341+
scratch.file(
342+
"test/test.bzl",
343+
"def save_as_dict(r):",
344+
" test.save('type(dict(r))', type(dict(r)))",
345+
" test.save('dict(r)[\"name\"]', dict(r)[\"name\"])",
346+
" test.save('dict(r)[\"kind\"]', dict(r)[\"kind\"])");
347+
scratch.file(
348+
"test/BUILD",
349+
"load('//test:test.bzl', 'save_as_dict')", //
350+
"cc_library(",
351+
" name ='rulename',",
352+
")",
353+
"save_as_dict(existing_rule('rulename'))");
354+
getConfiguredTarget("//test:rulename");
355+
assertThat(getSaved("type(dict(r))")).isEqualTo("dict");
356+
assertThat(getSaved("dict(r)[\"name\"]")).isEqualTo("rulename");
357+
assertThat(getSaved("dict(r)[\"kind\"]")).isEqualTo("cc_library");
358+
}
359+
360+
@Test
361+
public void existingRule_asDictUpdateArgument() throws Exception {
362+
// We do not test `existing_rule(r).update({...})` because `existing_rule(r)` may be immutable
363+
// (as verified by other test cases).
364+
scratch.file(
365+
"test/test.bzl",
366+
"def save_as_updated_dict(r):",
367+
" updated_dict = {'name': 'dictname', 'dictkey': 1}",
368+
" updated_dict.update(r)",
369+
" test.save('updated_dict[\"name\"]', updated_dict[\"name\"])",
370+
" test.save('updated_dict[\"kind\"]', updated_dict[\"kind\"])",
371+
" test.save('updated_dict[\"dictkey\"]', updated_dict[\"dictkey\"])");
372+
scratch.file(
373+
"test/BUILD",
374+
"load('//test:test.bzl', 'save_as_updated_dict')", //
375+
"cc_library(",
376+
" name ='rulename',",
377+
")",
378+
"save_as_updated_dict(existing_rule('rulename'))");
379+
getConfiguredTarget("//test:rulename");
380+
assertThat(getSaved("updated_dict[\"name\"]")).isEqualTo("rulename");
381+
assertThat(getSaved("updated_dict[\"kind\"]")).isEqualTo("cc_library");
382+
assertThat(getSaved("updated_dict[\"dictkey\"]")).isEqualTo(StarlarkInt.of(1));
383+
}
384+
339385
@Test
340386
public void existingRule_asKwargs() throws Exception {
341387
scratch.file(

0 commit comments

Comments
 (0)