__builtins__ magic behavior

Patrick Maupin pmaupin at gmail.com
Sun Sep 7 19:00:48 CEST 2008

__builtins__ in 2.5.2 doesn't seem to behave like I remember it did
the last time I did some custom stuff with it, a very long time ago.

This isn't surprising, because of ongoing optimization, but it's hard
to google for '__builtins__' so I didn't really find any documentation
on the current CPython behavior, which in some cases seems quite
strange to me.

The documentation node at http://docs.python.org/ref/naming.html has a
"here be dragons" note on __builtins__, which is nice as far as it
goes, but doesn't provide any help for people wanting to abuse the
current CPython implementation.  Additionally, the sentence
immediately above the note, "__builtins__ can be set to a user-created
dictionary to create a weak form of restricted execution" not only
contradicts the note, but in some cases appears not to be true.

When the code below is run, either standalone or by importing it, the
builtins used are different depending on whether exec is used with
globals() or with a copy of globals().  Any explanations for this
behavior would be much appreciated.


original = __builtins__
if hasattr(original, '__dict__'): original = original.__dict__
copy = original.copy()

# Make the dictionaries different and use new one
copy['foo'] = 'bar'
del copy['len']
del original['chr']
__builtins__ = copy

testcode = '''
try: print foo
except: print "foo not found"
try: print len
except: print "len not found"
try: print chr
except: print "chr not found"

x = globals()
assert type(x) is dict
y = {}
assert y == x

print 'Executing in globals()'
exec testcode in x

print 'Executing in copy'
exec testcode in y

results in:

Executing in globals()
foo not found
<built-in function len>
chr not found

Executing in copy
len not found
<built-in function chr>

More information about the Python-list mailing list