2012/1/21 Stefan Behnel <stefan...@behnel.de>: > Chris Colbert, 19.01.2012 09:18: >> If it doesn't pass PyDict_CheckExact you won't be able to use it as the >> globals to eval or exec. > > What makes you say that? I tried and it worked for me, all the way back to > Python 2.4: > > -------------------- > Python 2.4.6 (#2, Jan 21 2010, 23:45:25) > [GCC 4.4.1] on linux2 > Type "help", "copyright", "credits" or "license" for more information. >>>> class MyDict(dict): pass >>>> eval('1+1', MyDict()) > 2 >>>> exec '1+1' in MyDict() >>>> > -------------------- > > I only see a couple of calls to PyDict_CheckExact() in CPython's sources > and they usually seem to be related to special casing for performance > reasons. Nothing that should impact a module's globals. > > Besides, Cython controls its own language usages of eval and exec. >
Cool! It seems that python internally uses PyObject_GetItem() for module level lookups and not PyDict_GetItem(). Btw we use __Pyx_GetName() that calls PyObject_GetAttr() that isn't exactly the same for module lookups: # Works in Cython and doesn't work in Python print __class__ So we can override __getitem__() and __setitem__(): class MyDict(dict): def __init__(self): self._dict = {} def __getitem__(self, key): print '__getitem__', key return self._dict[key] def __setitem__(self, key, value): print '__setitem__', key, value self._dict[key] = value def __getattr__(self, key): print '__getattr__' d = MyDict() exec('x = 1; print x', d) eval('x', d) $ python foo.py __setitem__ x 1 __getitem__ x 1 __getitem__ x So we can make globals() return special dict with custom __setitem__()/__getitem__(). But it seems that we'll have to override many dict's standard methods like values(), update() and so on. That would be hard. -- vitja. _______________________________________________ cython-devel mailing list cython-devel@python.org http://mail.python.org/mailman/listinfo/cython-devel