]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-96151: Use a private name for passing builtins to dataclass. This now allows for...
authorShantanu <12621235+hauntsaninja@users.noreply.github.com>
Mon, 31 Oct 2022 12:31:01 +0000 (05:31 -0700)
committerGitHub <noreply@github.com>
Mon, 31 Oct 2022 12:31:01 +0000 (08:31 -0400)
Lib/dataclasses.py
Lib/test/test_dataclasses.py
Misc/NEWS.d/next/Library/2022-10-10-07-07-31.gh-issue-96151.K9fwoq.rst [new file with mode: 0644]

index bf7f290af1622fb27730659152b2ae661c4a23f9..b54e16984cb15c1a6fa53c13f357f4ccf5abdff5 100644 (file)
@@ -426,13 +426,11 @@ def _recursive_repr(user_function):
 
 def _create_fn(name, args, body, *, globals=None, locals=None,
                return_type=MISSING):
-    # Note that we mutate locals when exec() is called.  Caller
-    # beware!  The only callers are internal to this module, so no
+    # Note that we may mutate locals. Callers beware!
+    # The only callers are internal to this module, so no
     # worries about external callers.
     if locals is None:
         locals = {}
-    if 'BUILTINS' not in locals:
-        locals['BUILTINS'] = builtins
     return_annotation = ''
     if return_type is not MISSING:
         locals['_return_type'] = return_type
@@ -462,7 +460,7 @@ def _field_assign(frozen, name, value, self_name):
     # self_name is what "self" is called in this function: don't
     # hard-code "self", since that might be a field name.
     if frozen:
-        return f'BUILTINS.object.__setattr__({self_name},{name!r},{value})'
+        return f'__dataclass_builtins_object__.__setattr__({self_name},{name!r},{value})'
     return f'{self_name}.{name}={value}'
 
 
@@ -569,6 +567,7 @@ def _init_fn(fields, std_fields, kw_only_fields, frozen, has_post_init,
     locals.update({
         'MISSING': MISSING,
         '_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY,
+        '__dataclass_builtins_object__': object,
     })
 
     body_lines = []
index 637c456dd49e7a825a93a81324072ba9303ecaef..01e66840085bffa8437fa2c5f9ea71a3cbaba1d1 100644 (file)
@@ -257,6 +257,14 @@ class TestCase(unittest.TestCase):
         c = C('foo')
         self.assertEqual(c.object, 'foo')
 
+    def test_field_named_BUILTINS_frozen(self):
+        # gh-96151
+        @dataclass(frozen=True)
+        class C:
+            BUILTINS: int
+        c = C(5)
+        self.assertEqual(c.BUILTINS, 5)
+
     def test_field_named_like_builtin(self):
         # Attribute names can shadow built-in names
         # since code generation is used.
diff --git a/Misc/NEWS.d/next/Library/2022-10-10-07-07-31.gh-issue-96151.K9fwoq.rst b/Misc/NEWS.d/next/Library/2022-10-10-07-07-31.gh-issue-96151.K9fwoq.rst
new file mode 100644 (file)
index 0000000..700c974
--- /dev/null
@@ -0,0 +1 @@
+Allow ``BUILTINS`` to be a valid field name for frozen dataclasses.