TL;DR: it is hard, but not impossible, to set function `__globals__` dunder to a ChainMap. Let's make it easier!
Background: (1) Comprehensions skip class scope, leading to bug reports like these: https://bugs.python.org/issue3692 https://bugs.python.org/issue26951 Note Guido's comment in the first: "perhaps __globals__ could be set to a chainmap referencing the class dict and the globals?" (2) I want to experiment with namespaces, similar to the C++ feature. The details don't matter, but one way I can do that experiment is to use a class and ChainMap. So let's try an experiment: set up a namespace using ChainMap, and try to monkey-patch a function to use it instead of the regular globals. Here is my setup code: def func(): return (a, b, c) a = b = c = "global" from collections import ChainMap ns = ChainMap({'a': 'CM-0'}, {'b': 'CM-1'}, globals()) Let's see what it takes to set func.__globals__ to ns. Attempt 1: set __globals__ directly. >>> func.__globals__ = ns Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: readonly attribute Attempt 2: use the FunctionType constructor. >>> from types import FunctionType >>> f = FunctionType(func.__code__, globals=ns) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: function() argument 'globals' must be dict, not ChainMap Attempt 3: fool the constructor. >>> class MyChainMap(ChainMap, dict): ... pass ... >>> ns = MyChainMap({'a': 'CM-0'}, {'b': 'CM-1'}, globals()) >>> f = FunctionType(func.__code__, globals=ns) Success! And now the function behaves as desired: >>> f() ('CM-0', 'CM-1', 'global') This was too hard! What can we do to make it easier? I think we should have: - allow func.__globals__ to be writable; - allow anything that inherits from the Mapping ABC. Thoughts? -- Steve _______________________________________________ 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/5AUFO6NMDR5XABYCEU2LKXVDBQDXORUT/ Code of Conduct: http://python.org/psf/codeofconduct/