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 <[email protected]> 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 <[email protected]> wrote:
>> On Wed, May 26, 2010 at 5:53 PM, Colin H <[email protected]> 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 <[email protected]> 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
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com