google / starlark-go

Starlark in Go: the Starlark configuration language, implemented in Go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

unexpected global variable referenced before assignment

Pussbebe2103 opened this issue · comments

Here's 2 scripts with -globalassign enabled, run the first one, and use its output as input/predeclared for the second one:

Script 1:

hello = [123, 456]
debug = False

Script 2:

print(hello)

It runs fine, but if you change the second script to:

if debug:
    hello = "hello world"

print(hello)

It will throw an unexpected error: global variable hello referenced before assignment

Why?

In Starlark and Python, within a function, an assignment statement creates a variable binding in the function, whether or not it is executed:

$ starlark
>>> def f():
...     if False:
...        x = 1
...     print(x)
... 
>>> f()
Traceback (most recent call last):
  <stdin>:1:2: in <expr>
  <stdin>:4:11: in f
Error: local variable x referenced before assignment
$ python3
>>> def f():
...    if False:
...      x = 1
...    print(x)
... 
>>> f()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in f
UnboundLocalError: cannot access local variable 'x' where it is not associated with a value
>>> 

But Starlark differs from Python in its treatment of the toplevel. The spec disallows loops and conditional assignments at toplevel (conditional assignments are just loops where n < 2!), and the -globalreassign flag in the Go implementation treats the toplevel like any other function.