[Python-Dev] Python3 compiled listcomp can't see local var
Nick Coghlan
ncoghlan at gmail.com
Wed Jun 6 09:51:55 EDT 2018
More information about the Python-Dev mailing list
Wed Jun 6 09:51:55 EDT 2018
- Previous message (by thread): [Python-Dev] Python3 compiled listcomp can't see local var - bug or feature?
- Next message (by thread): [Python-Dev] Python3 compiled listcomp can't see local var - bug or feature?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On 6 June 2018 at 15:31, Rob Cliffe via Python-Dev <python-dev at python.org> wrote: > Is this a bug or a feature? > Consider the following program: > > # TestProgram.py > def Test(): > # global x > x = 1 > exec(compile('print([x+1,x+2])', 'MyTest', 'exec')) > exec(compile('print([x+i for i in range(1,3)])', 'MyTest', 'exec')) > Test() > > In Python 2.7.15 the output is > > [2, 3] > [2, 3] > > In Python 3.6.5 the output is > [2, 3] > Traceback (most recent call last): > File "TestProgram.py", line 7, in <module> > Test() > File "TestProgram.py", line 6, in Test > exec(compile('print([x+i for i in range(1,3)])', 'MyTest', 'exec')) > File "MyTest", line 1, in <module> > File "MyTest", line 1, in <listcomp> > NameError: name 'x' is not defined > > If the "global x" declaration is uncommented, this "fixes" the Python > 3.6.5 behaviour, > i.e. no error occurs and the output is the same as for Python 2.7.15. > > *In other words, it looks as if in Python 3.6.5, the compiled list > comprehension* > *can "see" a pre-existing global variable but not a local one.* > Yes, this is expected behaviour - the two-namespace form of exec (which is what you get implicitly when you use it inside a function body) is similar to a class body, and hence nested functions (including the implicit ones created for comprehensions) can't see the top level local variables. You can override that and force the use of the single-namespace form by passing the locals() namespace into exec() explicitly: def explicit_local_namespace(): x = 1 exec(compile('print([x+i for i in range(1,3)])', 'MyTest', 'exec'), locals()) explicit_local_namespace() (Note: you'll then need to use collections.ChainMap instead of separate locals and globals namespaces if you want the exec'ed code to still be able to see the module globals in addition to the function locals) Cheers, Nick. -- Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20180606/45723401/attachment.html>
- Previous message (by thread): [Python-Dev] Python3 compiled listcomp can't see local var - bug or feature?
- Next message (by thread): [Python-Dev] Python3 compiled listcomp can't see local var - bug or feature?
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
More information about the Python-Dev mailing list