I needed to make a small modification to the workaround - I wasn't able to delete from 'stuff', as the definitions in exec()'d code won't run - they're relying on that being present at runtime. In practice the overhead of doing this is quite noticeable if you run your code like this a lot, and build up a decent sized context (which I do). It will obviously depend on the usage scenario though.
def define_stuff(user_code): context = {...} stuff = {} stuff.update(context) exec(user_code, stuff) return_stuff = {} return_stuff.update(stuff) del return_stuff['__builtins__'] for key in context: if key in return_stuff and return_stuff[key] == context[key]: del return_stuff[key] return return_stuff On Thu, May 27, 2010 at 2:13 AM, Colin H <hawk...@gmail.com> wrote: > Of course :) - I need to pay more attention. Your workaround should do > the trick. It would make sense if locals could be used for this > purpose, but the workaround doesn't add so much overhead in most > situations. Thanks for the help, much appreciated, > > Colin > > On Thu, May 27, 2010 at 2:05 AM, Guido van Rossum <gu...@python.org> wrote: >> On Wed, May 26, 2010 at 5:53 PM, Colin H <hawk...@gmail.com> wrote: >>> Thanks for the possible workaround - unfortunately 'stuff' will >>> contain a whole stack of things that are not in 'context', and were >>> not defined in 'user_code' - things that python embeds - a (very >>> small) selection - >>> >>> {..., 'NameError': <type 'exceptions.NameError'>, 'BytesWarning': >>> <type 'exceptions.BytesWarning'>, 'dict': <type 'dict'>, 'input': >>> <function input at 0x10047a9b0>, 'oct': <built-in function oct>, >>> 'bin': <built-in function bin>, ...} >>> >>> It makes sense why this happens of course, but upon return, the >>> globals dict is very large, and finding the stuff you defined in your >>> user_code amongst it is a very difficult task. Avoiding this problem >>> is the 'locals' use-case for me. Cheers, >> >> No, if taken literally that doesn't make sense. Those are builtins. I >> think you are mistaken that each of those (e.g. NameError) is in stuff >> -- they are in stuff['__builtins__'] which represents the built-in >> namespace. You should remove that key from stuff as well. >> >> --Guido >> >>> Colin >>> >>> On Thu, May 27, 2010 at 1:38 AM, Guido van Rossum <gu...@python.org> wrote: >>>> This is not easy to fix. The best short-term work-around is probably a >>>> hack like this: >>>> >>>> def define_stuff(user_code): >>>> context = {...} >>>> stuff = {} >>>> stuff.update(context) >>>> exec(user_code, stuff) >>>> for key in context: >>>> if key in stuff and stuff[key] == context[key]: >>>> del stuff[key] >>>> return stuff >>>> >>>> -- >>>> --Guido van Rossum (python.org/~guido) >>>> >>> >> >> >> >> -- >> --Guido van Rossum (python.org/~guido) >> > _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com