Some trivia about Python frame objects

September 22, 2009

Since I've been poking around in this area of CPython lately, here's some trivia associated with frame objects.

First, one might wonder if code executing at the module level literally has a CPython frame struct with f_locals being the same as f_globals, or if the C code just leaves f_locals null and fixes things up behind the scenes when you look from Python code. The answer turns out to be that CPython frame structures always have a real f_locals (Python) dictionary, and in module level code it is just another reference to the globals as you'd expect.

This surprised me because I had always assumed that f_locals dictionaries for function-level frames were only materialized on (rare) demand. Instead there's always a dictionary, although its contents are allowed to get out of date with the real local variables as long as no Python code is looking at it.

(There are various interesting efficiency hacks to make creation and destruction of frame objects faster than you might expect.)

Second and probably obviously: there's no way to directly update the builtins namespace. This is both a language issue (there's no builtin analog to the global keyword) and an issue with the bytecode interpreter; in order to support direct updates of the builtin namespace, the bytecode interpreter would need a new STORE_BUILTIN opcode, as STORE_GLOBAL naturally only updates the f_globals namespace.

Now, consider the following code:

eval = eval
def t():
    global file
    file = file

This peculiar do-nothing code actually does do something: it creates module-level shadows of the eval and file builtins. This is one of the least obvious cases in which the left hand side of an assignment can be in a different namespace than the right hand side despite using the exact same variable names. (Or not, if you've already executed these statements once.)

(Previously I said that there were only two cases of such namespace differences; I was wrong then, or at least insufficiently perverse.)

Written on 22 September 2009.
« Exploring the frame object f_builtins member
A brief overview of the Solaris 10 nvpair library »

Page tools: View Source, Add Comment.
Search:
Login: Password:
Atom Syndication: Recent Comments.

Last modified: Tue Sep 22 01:35:47 2009
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.