starlark icon indicating copy to clipboard operation
starlark copied to clipboard

Spec: mutable types are unhashable even when frozen

Open stepancheg opened this issue 4 years ago • 3 comments
trafficstars

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

stepancheg avatar Nov 26 '20 22:11 stepancheg

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

alandonovan avatar Nov 30 '20 17:11 alandonovan

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.

stepancheg avatar Dec 04 '20 05:12 stepancheg

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.

alandonovan avatar Dec 04 '20 13:12 alandonovan