]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-42990: Add __builtins__ attribute to functions (GH-24559)
authorVictor Stinner <vstinner@python.org>
Thu, 18 Feb 2021 11:35:37 +0000 (12:35 +0100)
committerGitHub <noreply@github.com>
Thu, 18 Feb 2021 11:35:37 +0000 (12:35 +0100)
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.

Doc/library/inspect.rst
Doc/whatsnew/3.10.rst
Lib/test/test_collections.py
Lib/test/test_funcattrs.py
Misc/NEWS.d/next/Core and Builtins/2021-02-17-19-02-21.bpo-42990.SKXHiI.rst [new file with mode: 0644]
Objects/funcobject.c

index 850d6018bab1f98890d28749b49fdfd98609c4f6..10339641c3b4350e06a7cb53082e60d8914881bb 100644 (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)``
index 0fba27c7d5845c269a7000f1b98cf698311a1479..b903b3e0b81d9f26ea6d47b5a5ec5e2c74d0c098 100644 (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
 ===========
index befb7ab436c40af836509a985845f82188cfd2e9..54a4cbed44e37911805f7b420355e2be071923a4 100644 (file)
@@ -682,9 +682,10 @@ class TestNamedTuple(unittest.TestCase):
         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__, {})
 
 
 ################################################################################
index 11d68cc75e208995fca88fd60389bda98401f4bc..15cf250f192a95a6bc0eaef0d773daadc340e2d9 100644 (file)
@@ -73,6 +73,11 @@ class FunctionPropertiesTest(FuncAttrsTest):
         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)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-02-17-19-02-21.bpo-42990.SKXHiI.rst b/Misc/NEWS.d/next/Core and Builtins/2021-02-17-19-02-21.bpo-42990.SKXHiI.rst
new file mode 100644 (file)
index 0000000..cc17154
--- /dev/null
@@ -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.
index b331c4c4d6e351aab7c48450234dd6b5cc990501..523930da8dc6247bf115d50bfeeb80eac19cdb8d 100644 (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 */
 };