I've been playing around with ChainedMap in Python 3.3, and run into something which perplexes me. Let's start with an ordinary function that accesses one global and one builtin.
x = 42 def f(): print(x) If you call f(), it works as expected. But let's make a version with no access to builtins, and watch it break: from types import FunctionType g = FunctionType(f.__code__, {'x': 23}) If you call g(), you get an exception: py> g() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 2, in f NameError: global name 'print' is not defined (Don't be fooled by the traceback referring to "f" rather than g. That's because g's code was copied from f.) We can add support for builtins: import builtins # use __builtin__ with no "s" in Python 2 g.__globals__['__builtins__'] = builtins # Note the "s" in the key. and now calling g() prints 23, as expected. Now let me try the same thing using Python 3.3's ChainMap. Unfortunately, functions insist that their __global__ is a dict, so we fool it into accepting a ChainMap with some multiple inheritance trickery: from collections import ChainMap class ChainedDict(ChainMap, dict): pass d = ChainedDict({}, {'x': 23}, {'x': 42}) assert d['x'] == 23 g = FunctionType(f.__code__, d) As before, calling g() raises NameError, "global name 'print' is not defined". So I expected to be able to fix it just as I did before: g.__globals__['__builtins__'] = builtins But it doesn't work -- I still get the same NameError. Why does this not work here, when it works for a regular dict? I can fix it by adding the builtins into the ChainMap: g.__globals__.maps.append(builtins.__dict__) And now calling g() prints 23 as expected. -- Steven -- http://mail.python.org/mailman/listinfo/python-list