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 | | | __globals__ | global namespace in which |
| | | this function was defined | | | | this function was defined |
+-----------+-------------------+---------------------------+ +-----------+-------------------+---------------------------+
| | __builtins__ | builtins namespace |
+-----------+-------------------+---------------------------+
| | __annotations__ | mapping of parameters | | | __annotations__ | mapping of parameters |
| | | names to annotations; | | | | names to annotations; |
| | | ``"return"`` key is | | | | ``"return"`` key is |
@ -251,6 +253,10 @@ attributes:
Add ``cr_origin`` attribute to coroutines. Add ``cr_origin`` attribute to coroutines.
.. versionchanged:: 3.10
Add ``__builtins__`` attribute to functions.
.. function:: getmembers(object[, predicate]) .. function:: getmembers(object[, predicate])
Return all the members of an object in a list of ``(name, value)`` 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 * Assignment expressions can now be used unparenthesized within set literals
and set comprehensions, as well as in sequence indexes (but not slices). 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 New Modules
=========== ===========

View file

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

View file

@ -73,6 +73,11 @@ class FunctionPropertiesTest(FuncAttrsTest):
self.cannot_set_attr(self.b, '__globals__', 2, self.cannot_set_attr(self.b, '__globals__', 2,
(AttributeError, TypeError)) (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): def test___closure__(self):
a = 12 a = 12
def f(): print(a) 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}, {"__doc__", T_OBJECT, OFF(func_doc), 0},
{"__globals__", T_OBJECT, OFF(func_globals), READONLY}, {"__globals__", T_OBJECT, OFF(func_globals), READONLY},
{"__module__", T_OBJECT, OFF(func_module), 0}, {"__module__", T_OBJECT, OFF(func_module), 0},
{"__builtins__", T_OBJECT, OFF(func_builtins), READONLY},
{NULL} /* Sentinel */ {NULL} /* Sentinel */
}; };