[Python-Dev] PEP 3000 and exec
Brett Cannon
bcannon at gmail.com
Tue Oct 11 00:15:39 CEST 2005
On 10/10/05, skip at pobox.com <skip at pobox.com> wrote:
> >> This might be minor-- but I didn't see anyone mentioning it so far.
> >> If `exec` functionality is to be provided, then I think it still
> >> should be a keyword for the parser to know; currently bytecode
> >> generation is affected if `exec` is present. Even if that changes
> >> for Python 3k (we don't know yet), the paragraph for exec should be
> >> annotated with a note about this issue.
>
> Brett> But the PEP says that 'exec' will become a function and thus no
> Brett> longer become a built-in, so changing the grammar is not needed.
>
> I don't think that was the OP's point though it might not have been terribly
> clear. Today, the presence of the exec statement in a function changes how
> non-local load instructions are generated. Consider f and g with their
> dis.dis output:
>
> >>> def f(a):
> ... exec "import %s" % a
> ... print q
> ...
> >>> def g(a):
> ... __import__(a)
> ... print q
> ...
> >>> dis.dis(f)
> 2 0 LOAD_CONST 1 ('import %s')
> 3 LOAD_FAST 0 (a)
> 6 BINARY_MODULO
> 7 LOAD_CONST 0 (None)
> 10 DUP_TOP
> 11 EXEC_STMT
>
> 3 12 LOAD_NAME 1 (q)
> 15 PRINT_ITEM
> 16 PRINT_NEWLINE
> 17 LOAD_CONST 0 (None)
> 20 RETURN_VALUE
> >>> dis.dis(g)
> 2 0 LOAD_GLOBAL 0 (__import__)
> 3 LOAD_FAST 0 (a)
> 6 CALL_FUNCTION 1
> 9 POP_TOP
>
> 3 10 LOAD_GLOBAL 2 (q)
> 13 PRINT_ITEM
> 14 PRINT_NEWLINE
> 15 LOAD_CONST 0 (None)
> 18 RETURN_VALUE
>
> If the exec statement is replaced by a function, how will the bytecode
> generator know that q should be looked up using LOAD_NAME instead of
> LOAD_GLOBAL? Maybe it's a non-issue, but even if so, a note to that affect
> on the wiki page might be worthwhile.
Ah, OK. That makes more sense. For a quick, on-the-spot answer, one
possibility is for the 'exec' function to examine the execution stack,
go back to the caller, and patch the bytecode so that it uses
LOAD_NAME instead of LOAD_GLOBAL. Total hack, but it would work and
since 'exec' is not exactly performance-critical to begin with
something this expensive wouldn't necessarily out of the question.
But the better answer is we will just find a way. =)
-Brett
More information about the Python-Dev
mailing list