Python Forum
namespaces in comprehension in exec()
Thread Rating:
  • 2 Vote(s) - 4 Average
  • 1
  • 2
  • 3
  • 4
  • 5
namespaces in comprehension in exec()
#1
first, here is the (nearly) minimalized code by itself:

s="foo = 1\nfor n in range(10):\n    x = [n**m for m in range(9)]\nbar = 0"
g={}
l={}
print(s)
exec(s,g,l)
print(repr(l))
secondly here is the output i get:
Output:
lt1/forums /home/forums 6> py3 --version Python 3.5.2 lt1/forums /home/forums 7> cat try.py s="foo = 1\nfor n in range(10):\n    x = [n**m for m in range(9)]\nbar = 0" g={} l={} print(s) exec(s,g,l) print(repr(l)) lt1/forums /home/forums 8> py3 try.py foo = 1 for n in range(10):     x = [n**m for m in range(9)] bar = 0 Traceback (most recent call last):   File "try.py", line 5, in <module>     exec(s,g,l)   File "<string>", line 3, in <module>   File "<string>", line 3, in <listcomp> NameError: name 'n' is not defined lt1/forums /home/forums 9>
it looks like that while executing under exec(), the local namespace is not used in a comprehension.  it works as expected under python2:
Output:
lt1/forums /home/forums 10> py2 --version Python 2.7.12 lt1/forums /home/forums 11> cat try.py s="foo = 1\nfor n in range(10):\n    x = [n**m for m in range(9)]\nbar = 0" g={ l={} print(s) exec(s,g,l) print(repr(l)) lt1/forums /home/forums 12> py2 try.py foo = 1 for n in range(10):     x = [n**m for m in range(9)] bar = 0 {'x': [1, 9, 81, 729, 6561, 59049, 531441, 4782969, 43046721], 'foo': 1, 'm': 8, 'bar': 0, 'n': 9} lt1/forums /home/forums 13>
i did not get that empty line that appears to be output by command 10.  that's a bug in MyBB somewhere.  i take it out and posting puts it back in (could be a bug in the client side code).  now it moved it to command 11. got it out this time. but it remove the closing brace of the empty dict assignment to g.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#2
List comprehensions were changed in python 3 (to prevent leaking of "inside" variables) and have proper scope. And thats reason why inside of list comprehension defined in the class you cant see class variables - its explained in Accessing class variables from a list comprehension in the class definition

And as its explicitily stated in exec docs:
Quote:If exec gets two separate objects as globals and locals, the code will be executed as if it were embedded in a class definition.

So use only globals directory (why you need to pass locals anyway?) or rewrite your list comprehension as a for loop.
Reply
#3
(Mar-27-2017, 08:40 AM)zivoni Wrote: why you need to pass locals anyway?

i am making "python format" config files.  that means lots of simple coding will be used that just does put things in the local namespace.

account = "080643210675"
vin = "1HGBH41JXMN109186"
phone = "+18009004321"
it doesn't have to be locals.  it just has to be somewhere.  if nothing else is added to to the space then there is the option to extract "misspelled" config options.  but the global space gets stuff added so it is to be avoid if that option is to be used.  my pyconf() function was intended to return a dictionary of what the config file set.  so, the issue of how comprehensions are used is going to be used will be the same in a python format config file as in regular code.  no big deal.  however people deal with it in regular code, just do the same in a python format config file.  use of comprehensions in config files is expected to be much less frequent in config files than in regular code.  and they are rare in regular code.  it was just a happen chance that i used one.  i did not know of the namespace isolation thing.  now i do.
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply
#4
(Mar-27-2017, 10:11 AM)Skaperen Wrote: it doesn't have to be locals.  it just has to be somewhere.  if nothing else is added to to the space then there is the option to extract "misspelled" config options.  but the global space gets stuff added so it is to be avoid if that option is to be used.  my pyconf() function was intended to return a dictionary of what the config file set.  so, the issue of how comprehensions are used is going to be used will be the same in a python format config file as in regular code.  no big deal.

Isolation of executed code can be achieved just with globals parameter (globals parameter has nothing common with global scope (globals()) from where you use exec). And with regular import comprehensions would work, problem is with locals parameter enforcing "class definition execution".

>>> s = "boo=1"
>>> config = {}
>>> exec(s, config)
>>> boo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'boo' is not defined
>>> config['boo']
1
Reply
#5
(Mar-27-2017, 12:22 PM)zivoni Wrote:
(Mar-27-2017, 10:11 AM)Skaperen Wrote: it doesn't have to be locals.  it just has to be somewhere.  if nothing else is added to to the space then there is the option to extract "misspelled" config options.  but the global space gets stuff added so it is to be avoid if that option is to be used.  my pyconf() function was intended to return a dictionary of what the config file set.  so, the issue of how comprehensions are used is going to be used will be the same in a python format config file as in regular code.  no big deal.

Isolation of executed code can be achieved just with globals parameter (globals parameter has nothing common with global scope (globals()) from where you use exec). And with regular import comprehensions would work, problem is with locals parameter enforcing "class definition execution".

>>> s = "boo=1"
>>> config = {}
>>> exec(s, config)
>>> boo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'boo' is not defined
>>> config['boo']
1

why is this so important?
Tradition is peer pressure from dead people

What do you call someone who speaks three languages? Trilingual. Two languages? Bilingual. One language? American.
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Still not completely clear about namespaces... bytecrunch 3 1,927 Oct-07-2022, 05:44 PM
Last Post: bytecrunch
  How to avoid exec(), globals(), locals(), eval() paul18fr 10 5,011 Apr-21-2021, 05:53 PM
Last Post: snippsat
  exec in a function paul18fr 6 3,369 Apr-19-2021, 11:10 AM
Last Post: paul18fr
  exec + subprocess = UnboundLocalError paul18fr 6 3,488 Feb-04-2021, 06:27 AM
Last Post: Gribouillis
  Modules and namespaces (again?) ptrivino 1 1,849 Oct-24-2020, 10:37 PM
Last Post: Larz60+
  exec() in class, NameError niski1996 6 3,964 Apr-20-2020, 07:14 PM
Last Post: niski1996
  Is this use of exec pythonic? psolar 1 1,830 Feb-07-2020, 12:23 PM
Last Post: buran
  problem using exec to save local variables dkarl 0 1,787 Dec-01-2019, 08:52 AM
Last Post: dkarl
  common code, def a function vs exec() a string Skaperen 7 3,338 May-27-2019, 10:13 AM
Last Post: heiner55
  Parse XML with Namespaces dwill 7 20,365 Apr-12-2018, 09:22 PM
Last Post: dwill

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020