News for hackers. Stuff that matters.
Re:Show HN: Cannoli – A compiler for a subset of Python writ... by Erwin on Thursday May 17, 2018 @06:47PM (#17096809)
In Python 2, the bytecode optimization that lets you access variables by index is turned off if your function has exec code in it that may modify locals.

So if your function is:

   def foo(): exec "a=1"; return a
Then running dis.dis on foo to disassemble the bytecode it you will see:

              8 LOAD_NAME                0 (a)
while you normally would see:

              6 LOAD_FAST                0 (a)
You can't use the exec in locals thing in Python 3 at all I believe.
Re:Show HN: Cannoli – A compiler for a subset of Python writ... by speedster217 on Thursday May 17, 2018 @08:03PM (#17097399)
I just tested it in Python3:

    def foo():
        exec("a=1")
        return a

    print(foo())
Fails with a NameError:

    Traceback (most recent call last):
      File "test.py", line 5, in <module>
        print(foo())
      File "test.py", line 3, in foo
        return a
    NameError: name 'a' is not defined
Re:Show HN: Cannoli – A compiler for a subset of Python writ... by joncatanio on Thursday May 17, 2018 @08:41PM (#17097658)
I get the same error with your example, but this works fine (Python 3.6.4):

    exec("a = 1")
    print(a)
This will print "1".
Re:Show HN: Cannoli – A compiler for a subset of Python writ... by yorwba on Thursday May 17, 2018 @10:33PM (#17098224)
That is because the exec runs in the global scope. When Python sees a variable that is not assigned to in the local scope, it is assumed to be a global variable, so when exec creates a new local variable, the load still fails because it looks into the globals dictionary.

But you can do this:

  def foo():
    exec("a = 1")
    return locals()['a']
Re:Show HN: Cannoli – A compiler for a subset of Python writ... by joncatanio on Thursday May 17, 2018 @07:44PM (#17097253)
Ahh, I see, this makes more sense. Thanks for the clarification!