Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot declare multiple classes via exec when inside a function. #48631

Closed
kfitch mannequin opened this issue Nov 21, 2008 · 2 comments
Closed

Cannot declare multiple classes via exec when inside a function. #48631

kfitch mannequin opened this issue Nov 21, 2008 · 2 comments

Comments

@kfitch
Copy link
Mannequin

kfitch mannequin commented Nov 21, 2008

BPO 4381
Nosy @amauryfa

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2008-11-21.21:53:43.060>
created_at = <Date 2008-11-21.20:33:45.006>
labels = []
title = 'Cannot declare multiple classes via exec when inside a function.'
updated_at = <Date 2008-11-21.21:53:43.058>
user = 'https://bugs.python.org/kfitch'

bugs.python.org fields:

activity = <Date 2008-11-21.21:53:43.058>
actor = 'amaury.forgeotdarc'
assignee = 'none'
closed = True
closed_date = <Date 2008-11-21.21:53:43.060>
closer = 'amaury.forgeotdarc'
components = []
creation = <Date 2008-11-21.20:33:45.006>
creator = 'kfitch'
dependencies = []
files = []
hgrepos = []
issue_num = 4381
keywords = []
message_count = 2.0
messages = ['76202', '76205']
nosy_count = 2.0
nosy_names = ['amaury.forgeotdarc', 'kfitch']
pr_nums = []
priority = 'normal'
resolution = 'wont fix'
stage = None
status = 'closed'
superseder = None
type = None
url = 'https://bugs.python.org/issue4381'
versions = ['Python 2.5']

@kfitch
Copy link
Mannequin Author

kfitch mannequin commented Nov 21, 2008

codeText = """
class foo(object): pass
class bar(object):
  baz = foo()
"""

def doExec(text):
  exec text

### This works:
# Although if I do this before the doExec below, then the
# doExec doesn't fail.
# exec codeText

### But this does not:
doExec(codeText)

The output I get is:
---------------------------------------------------------------------------

<type 'exceptions.NameError'>             Traceback (most recent call last)

/home/kfitch/<ipython console> in <module>()

/home/kfitch/<ipython console> in doExec(text)

/home/kfitch/<string> in <module>()

/home/kfitch/<string> in bar()

<type 'exceptions.NameError'>: name 'foo' is not defined

I don't fully understand why the version in the function doesn't work,
but I suspect it is a bug related to scoping, since foo is really
doExec.foo (I think).

This is with python 2.5.2 under Linux (Ubuntu 8.04)

@amauryfa
Copy link
Member

I agree that it is confusing; in short: a bare exec() does not play well with closures;
This is a consequence of the python execution model, and is unlikely to change.

Here, the class 'foo' is stored in the function's local variables.
But the execution of the body of the 'bar' class searches names in its local scope (the
class body) and the global scope (the module level), and misses the function's
locals...

I strongly suggest to avoid pure exec() statements; always specify a global and/or a
local dictionary.

In your case, the following works:

def doExec(text):
  d = {}  # or:   d = dict(globals())
  exec text in d
  print d.keys()

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant