Closed tabreturn closed 3 years ago
@tabreturn You're giving me a challenging bug to fix today....
Oddly, prepending that code with global x
makes the error go away.
This has the same problem:
foo = 42
def test(bar):
return foo + bar
print(test(1))
The issue seems to be with how py5bot and run_sketch compile and execute static mode code. I have an idea for how to investigate but will save it for tomorrow.
Fixed.
Like a lot of bugs, the path forward starts with isolating the problem. In this case I could reproduce it with this:
test_code = """
x = 10
[i*x for i in range(10)]
"""
def test_function():
exec(test_code)
test_function()
That code can be fixed with this:
test_code = """
x = 10
[i*x for i in range(10)]
"""
ns1 = {}
def test_function():
exec(test_code, ns1)
test_function()
Interestingly, this doesn't fix it:
test_code = """
x = 10
[i*x for i in range(10)]
"""
ns1 = {}
ns2 = {}
def test_function():
exec(test_code, ns1, ns2)
test_function()
What's happening here is that it stores x
in the local namespace but then tries to retrieve it from the global namespace in the second line. If both namespaces are the same, it works. exec()
by default separates them, using locals()
and globals()
.
This fix relates to #40.
At the end of #40 I wrote:
I think I have everything working now. I also add sensible
global
support for py5bot, even though using theglobal
keyword outside of a function is a bit dubious. Not supporting this would potentially lead to other confusing problems for users.
Previously you could use the global
keyword in py5bot and the py5 magics like %%py5draw
but that will no longer have any effect. That's probably for the best as that was really an implementation side effect and not a real feature anyone should be using.
Both of these bugs helped improve an important part of py5. Thank you for reporting them.
Running this:
produces this error:
This, however, works fine --