Allow dicts to contain non-comparable objects as keys
RELNOTES: Skylark dicts internally don't rely on keys order anymore and accept
any hashable values (i.e. structs with immutable values) as keys. Iteration order of dictionaries is no longer specified.
--
PiperOrigin-RevId: 141055080
MOS_MIGRATED_REVID=141055080
diff --git a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
index b2a33c5..fd79759 100644
--- a/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
+++ b/src/main/java/com/google/devtools/build/lib/syntax/MethodLibrary.java
@@ -1314,12 +1314,7 @@
+ "<code>popitem()</code> is useful to destructively iterate over a dictionary, "
+ "as often used in set algorithms. "
+ "If the dictionary is empty, calling <code>popitem()</code> fails. "
- + "Note that in Skylark, as opposed to Python, "
- + "the dictionary keys are actually sorted, "
- + "and it is deterministic which pair will returned: that with the first key, "
- + "according to the builtin total order. "
- + "Thus if keys are numbers, the smallest key is returned first; "
- + "if they are lists or strings, they are compared lexicographically, etc.",
+ + "It is deterministic which pair is returned.",
parameters = {
@Param(name = "self", type = SkylarkDict.class, doc = "This dict.")
},
@@ -1432,9 +1427,9 @@
objectType = SkylarkDict.class,
returnType = MutableList.class,
doc =
- "Returns the list of values. Dictionaries are always sorted by their keys:"
+ "Returns the list of values:"
+ "<pre class=\"language-python\">"
- + "{2: \"a\", 4: \"b\", 1: \"c\"}.values() == [\"c\", \"a\", \"b\"]</pre>\n",
+ + "{2: \"a\", 4: \"b\", 1: \"c\"}.values() == [\"a\", \"b\", \"c\"]</pre>\n",
parameters = {@Param(name = "self", type = SkylarkDict.class, doc = "This dict.")},
useEnvironment = true
)
@@ -1450,9 +1445,9 @@
objectType = SkylarkDict.class,
returnType = MutableList.class,
doc =
- "Returns the list of key-value tuples. Dictionaries are always sorted by their keys:"
+ "Returns the list of key-value tuples:"
+ "<pre class=\"language-python\">"
- + "{2: \"a\", 4: \"b\", 1: \"c\"}.items() == [(1, \"c\"), (2, \"a\"), (4, \"b\")]"
+ + "{2: \"a\", 4: \"b\", 1: \"c\"}.items() == [(2, \"a\"), (4, \"b\"), (1, \"c\")]"
+ "</pre>\n",
parameters = {@Param(name = "self", type = SkylarkDict.class, doc = "This dict.")},
useEnvironment = true
@@ -1470,8 +1465,8 @@
@SkylarkSignature(name = "keys", objectType = SkylarkDict.class,
returnType = MutableList.class,
- doc = "Returns the list of keys. Dictionaries are always sorted by their keys:"
- + "<pre class=\"language-python\">{2: \"a\", 4: \"b\", 1: \"c\"}.keys() == [1, 2, 4]"
+ doc = "Returns the list of keys:"
+ + "<pre class=\"language-python\">{2: \"a\", 4: \"b\", 1: \"c\"}.keys() == [2, 4, 1]"
+ "</pre>\n",
parameters = {
@Param(name = "self", type = SkylarkDict.class, doc = "This dict.")},
@@ -1482,9 +1477,11 @@
@SuppressWarnings("unchecked")
public MutableList<?> invoke(SkylarkDict<?, ?> self,
Environment env) throws EvalException {
- return new MutableList(
- Ordering.natural().sortedCopy((Set<Comparable<?>>) (Set<?>) self.keySet()),
- env);
+ List<Object> list = Lists.newArrayListWithCapacity(self.size());
+ for (Map.Entry<?, ?> entries : self.entrySet()) {
+ list.add(entries.getKey());
+ }
+ return new MutableList(list, env);
}
};
@@ -1678,8 +1675,7 @@
doc =
"Creates a <a href=\"#modules.dict\">dictionary</a> from an optional positional "
+ "argument and an optional set of keyword arguments. Values from the keyword argument "
- + "will overwrite values from the positional argument if a key appears multiple times. "
- + "Dictionaries are always sorted by their keys",
+ + "will overwrite values from the positional argument if a key appears multiple times.",
parameters = {
@Param(
name = "args",