Reputation:
I ran into this when creating a script that exports dirs and mails to another account with exchangelib.
When I run code with "exec" it returns as not defined but earlier on in the same code it works.
This part doesn't work:
exec('a = van_account.inbox / ' + par + ' / ' + '"%s"' % fol + '; b = a.all().only("id", "changekey"); data = van_account.export(b); up = naar_account.upload((naar_account.inbox / ' + par + ' / ' + '"%s"' % fol + ', d) for d in data); print("[UPLOAD] %i mail geupload in %s" % (len(data), fol))')
This part is right above it and does work. This also refers to "naar_account":
code = "create = Folder(parent=naar_account.inbox / "
par = ' '.join('"{}" /'.format(word) for word in par.split('/'))[:-1]
exec(code + par + ', name="%s"); create.save()' % fol)
This also works:
exec('print(naar_account)')
Even renaming it works and than it says the renamed part is not defined:
exec('wtf = naar_account; a = van_account.inbox / ' + par + ' / ' + '"%s"' % fol + '; b = a.all().only("id", "changekey"); data = van_account.export(b); up = wtf.upload((wtf.inbox / ' + par + ' / ' + '"%s"' % fol + ', d) for d in data); print("[UPLOAD] %i mail geupload in %s" % (len(data), fol))')
Full code:
def search_levels(van_account, naar_account):
for subfolder in van_account.inbox.walk():
subfolder = subfolder.absolute
# If '/' means it has subfolders
if '/' in subfolder.replace(van_account.inbox.absolute + '/', ''):
# Strip fill path, leave only Inbox path
par = subfolder.replace(van_account.inbox.absolute + '/', '')
# Get last item, it's the Dir we need to create
fol = par.split('/')[-1]
# Replace last item, it's the Dir, we only need the parent
par = par.replace(par.split('/')[-1], '')[:-1]
code = "create = Folder(parent=naar_account.inbox / "
par = ' '.join('"{}" /'.format(word) for word in par.split('/'))[:-1]
exec(code + par + ', name="%s"); create.save()' % fol)
print('[Created] %s' % fol)
exec('print(naar_account)')
exec('a = van_account.inbox / ' + par + ' / ' + '"%s"' % fol + '; b = a.all().only("id", "changekey"); data = van_account.export(b); up = naar_account.upload((naar_account.inbox / ' + par + ' / ' + '"%s"' % fol + ', d) for d in data); print("[UPLOAD] %i mail geupload in %s" % (len(data), fol))')
else:
par = None
fol = subfolder.replace(van_account.inbox.absolute + '/', '')
create = Folder(parent=naar_account.inbox, name=fol)
create.save()
print('[Created] %s' % fol)
a = van_account.inbox / fol
b = a.all().only('id', 'changekey')
data = van_account.export(b)
up = naar_account.upload((naar_account.inbox / fol, d) for d in data)
print('[UPLOAD] %i mail geupload naar %s' % (len(data), fol))
Traceback (most recent call last):
File "./migrate.py", line 225, in <module>
start(van_adres, van_passwd, naar_adres, naar_passwd)
File "./migrate.py", line 114, in start
search_levels(van_account, naar_account)
File "./migrate.py", line 154, in search_levels
exec('a = van_account.inbox / ' + par + ' / ' + '"%s"' % fol + '; b = a.all().only("id", "changekey"); data = van_account.export(b); wtf = naar_account; up = wtf.upload((wtf.inbox / ' + par + ' / ' + '"%s"' % fol + ', d) for d in data); print("[UPLOAD] %i mail geupload in %s" % (len(data), fol))')
File "<string>", line 1, in <module>
File "/usr/local/lib/python3.7/site-packages/exchangelib/account.py", line 340, in upload
is_empty, data = peek(data)
File "/usr/local/lib/python3.7/site-packages/exchangelib/util.py", line 130, in peek
first = next(iterable)
File "<string>", line 1, in <genexpr>
NameError: name 'wtf' is not defined
Upvotes: 0
Views: 190
Reputation: 22152
wtf
is used in the exec
's scope but seemingly nowhere else, with exec
itself in a local scope. Therefore wtf
will be a local variable in the exec
scope. Modifications of the locals through exec
are not visible outside of it, therefore wtf
is not accessible from outside the exec
's scope at all.
Names in generator expressions (with the exception of the left-most for
expression) are evaluated lazily when __next__
is called. Therefore wtf
from wtf.inbox
will be looked up when __next__
is called.
That happens in some other function outside the exec
scope and therefore wtf
, being local to the latter, is not found there.
Upvotes: 1