On Tue, Jul 30, 2019 at 12:54:12PM +1000, Chris Angelico wrote: > A class + decorator gets so almost there that it might be possible > with just a tiny bit of language support. What if there could be a way > to change a function's __globals__? Currently that's readonly > according to funcobject.c, but by hacking that flag out, I can create > the following example:
That's one of the problems I hit in my experiments. I don't think you need to hack funcobject.c if you are willing to disassemble the function object (all of the parts are accessible as attributes) and re-assemble it into a new function using the types.FunctionType constructor. > Due to CPython limitations, the new __globals__ MUST be a plain dict > (not the mappingproxy that cls.__dict__ is, and not a ChainMap), In my experiments, I think I overcame that by subclassing ChainMap and dict: class MyChainMap(ChainMap, dict): pass was, I think, enough to fool the function constructor. Don't quote me on this, it's been a while and I don't remember all the details. But I'm pretty sure nothing segfaulted, I'd remember it if it did :-) I'm pretty sure that this is doable, at least well enough to get a working prototype that people can experiment with. At worst, we might need AST or bytecode hacking to get the functions defined inside the namespace to work correctly. > but > this is extremely close to what could actually be quite useful. Also, > since the function objects get mutated by the decorator, calling a > function during the namespace's construction will have the wrong > behaviour. Yes, there's that too. But then the namespace doesn't actually exist at that point, so this is rather analogous to what happens when you call a function inside a class during class construction. I can live with that limitation. -- Steven _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/PNBJWGT5DLJO2DP24NH2VC5TKHFFE5NZ/ Code of Conduct: http://python.org/psf/codeofconduct/