[prev in list] [next in list] [prev in thread] [next in thread]
List: python-ideas
Subject: [Python-ideas] Make it easier to set function globals
From: Steven D'Aprano <steve () pearwood ! info>
Date: 2021-12-12 2:19:51
Message-ID: 20211212021951.GL21647 () ando ! pearwood ! info
[Download RAW message or body]
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-leave@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/
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic