On Wed, 6 Jul 2016 01:27 am, eryk sun wrote: > On Tue, Jul 5, 2016 at 2:46 PM, Steven D'Aprano <st...@pearwood.info> > wrote: >> I've come across two curious behaviours of a function using custom >> globals. In both cases, I have a function where __globals__ is set to a >> ChainMap. > > ChainMap implements the MutableMapping abstract base class. But > CPython needs globals to be a dict. In the current implementation, > LOAD_GLOBAL calls _PyDict_LoadGlobal, and STORE_GLOBAL calls > PyDict_SetItem. They don't fall back on the abstract object APIs.
Which is why I use ChainDict, a subclass of ChainMap and dict. It's enough to allow the FunctionType constructor to accept the argument, and the assignment *appears* to take place. If PyDict_SetItem expects an actual dict (accept no substitutes or subclasses), why is there no error? I would have expected a segfault at worst or at least an exception. It works with exec: py> from collections import ChainMap py> class ChainDict(ChainMap, dict): ... pass ... py> m = ChainDict() py> exec("x = 1", m, m) py> m['x'] 1 (Tested in both 3.3 and 3.6.) -- Steven “Cheer up,” they said, “things could be worse.” So I cheered up, and sure enough, things got worse. -- https://mail.python.org/mailman/listinfo/python-list