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

Reply via email to