starlark
starlark copied to clipboard
Spec: mutable types are unhashable even when frozen
Motivation is this:
- it is not possible for user to freeze a value
- it might not be possible to provide ability to freeze individual values in all implementation architectures
- Python does not allow mutable types in dict keys
- we may relax this restriction later, and relaxing will be easier than restricting, so better restrict it earlier
Related issue: #64
it is not possible for user to freeze a value
True, but a user may assume that a value loaded from another module is frozen.
I agree with the motivation, and I like this change. However, according to this interpretation, the Java implementation has a serious bug: although a list or dict (frozen or unfrozen) is not suitable as a dict key, a struct or tuple containing frozen lists or dicts is suitable as a dict key. See: https://github.com/bazelbuild/bazel/blob/8bd6fbebe8835eefb18074c5eb993eeb59ab3272/src/main/java/net/starlark/java/eval/StarlarkValue.java#L84
(also Google internal issue b/120837801)
$ cat test/BUILD
unfrozendict={}
unfrozenlist=[]
load("inc.bzl", "frozendict", "frozenlist", struct="makestruct")
# print({unfrozendict: None}) # unhashable type: 'dict'
# print({unfrozenlist: None}) # unhashable type: 'list'
# print({frozendict: None}) # unhashable type: 'dict'
# print({frozenlist: None}) # unhashable type: 'list'
print({struct(f=frozendict): None}) # ok
print({struct(f=frozenlist): None}) # ok
# print({struct(f=unfrozendict): None}) # unhashable type: 'struct' (a poor error message)
# print({struct(f=unfrozenlist): None}) # unhashable type: 'struct'
$ cat test/inc.bzl
frozendict = {}
frozenlist = []
mystruct = struct
the Java implementation has a serious bug
This is obviously easy to fix.
We can introduce a new semantics key StarlarkSemantics.ALLOW_CERTAIN_MUTABLE_HASHING, on by default now, off by default later; to make migration easier.
This is obviously easy to fix.
Unfortunately that is not the case. Even a trivial syntactic change (like disallowing invalid escape sequences such as \k) requires days of cleanup in Google's code base. This change is very subtle, because it affects the semantics of analysis code. I expect it would require a month of work, and I would not be surprised if the effort got mired before completion.