bpo-42990: Add __builtins__ attribute to functions (GH-24559)

Expose the new PyFunctionObject.func_builtins member in Python as a
new __builtins__ attribute on functions.

Document also the behavior change in What's New in Python 3.10.
This commit is contained in:
Victor Stinner 2021-02-18 12:35:37 +01:00 committed by GitHub
parent 366dc3a135
commit a3c3ffa68e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 24 additions and 3 deletions

View file

@ -95,6 +95,8 @@ attributes:
| | __globals__ | global namespace in which |
| | | this function was defined |
+-----------+-------------------+---------------------------+
| | __builtins__ | builtins namespace |
+-----------+-------------------+---------------------------+
| | __annotations__ | mapping of parameters |
| | | names to annotations; |
| | | ``"return"`` key is |
@ -251,6 +253,10 @@ attributes:
Add ``cr_origin`` attribute to coroutines.
.. versionchanged:: 3.10
Add ``__builtins__`` attribute to functions.
.. function:: getmembers(object[, predicate])
Return all the members of an object in a list of ``(name, value)``

View file

@ -280,6 +280,11 @@ Other Language Changes
* Assignment expressions can now be used unparenthesized within set literals
and set comprehensions, as well as in sequence indexes (but not slices).
* Functions have a new ``__builtins__`` attribute which is used to look for
builtin symbols when a function is executed, instead of looking into
``__globals__['__builtins__']``.
(Contributed by Mark Shannon in :issue:`42990`.)
New Modules
===========

View file

@ -682,9 +682,10 @@ class NewPoint(tuple):
self.assertEqual(np.y, 2)
def test_new_builtins_issue_43102(self):
self.assertEqual(
namedtuple('C', ()).__new__.__globals__['__builtins__'],
{})
obj = namedtuple('C', ())
new_func = obj.__new__
self.assertEqual(new_func.__globals__['__builtins__'], {})
self.assertEqual(new_func.__builtins__, {})
################################################################################

View file

@ -73,6 +73,11 @@ def test___globals__(self):
self.cannot_set_attr(self.b, '__globals__', 2,
(AttributeError, TypeError))
def test___builtins__(self):
self.assertIs(self.b.__builtins__, __builtins__)
self.cannot_set_attr(self.b, '__builtins__', 2,
(AttributeError, TypeError))
def test___closure__(self):
a = 12
def f(): print(a)

View file

@ -0,0 +1,3 @@
Functions have a new ``__builtins__`` attribute which is used to look for
builtin symbols when a function is executed, instead of looking into
``__globals__['__builtins__']``. Patch by Mark Shannon and Victor Stinner.

View file

@ -250,6 +250,7 @@ static PyMemberDef func_memberlist[] = {
{"__doc__", T_OBJECT, OFF(func_doc), 0},
{"__globals__", T_OBJECT, OFF(func_globals), READONLY},
{"__module__", T_OBJECT, OFF(func_module), 0},
{"__builtins__", T_OBJECT, OFF(func_builtins), READONLY},
{NULL} /* Sentinel */
};