summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShantanu <12621235+hauntsaninja@users.noreply.github.com>2022-10-31 12:31:01 (GMT)
committerGitHub <noreply@github.com>2022-10-31 12:31:01 (GMT)
commit29f98b46b77ee528477b9a7b335974b9682f7f14 (patch)
treeb4c0b421d8c8412bd33bede75f41782b2a9fe250
parent87b5fd9d9de11c68b9940d3a1dba902138129109 (diff)
downloadcpython-29f98b46b77ee528477b9a7b335974b9682f7f14.zip
cpython-29f98b46b77ee528477b9a7b335974b9682f7f14.tar.gz
cpython-29f98b46b77ee528477b9a7b335974b9682f7f14.tar.bz2
gh-96151: Use a private name for passing builtins to dataclass. This now allows for a field named BUILTIN (gh-98143)
-rw-r--r--Lib/dataclasses.py9
-rw-r--r--Lib/test/test_dataclasses.py8
-rw-r--r--Misc/NEWS.d/next/Library/2022-10-10-07-07-31.gh-issue-96151.K9fwoq.rst1
3 files changed, 13 insertions, 5 deletions
diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py
index bf7f290..b54e169 100644
--- a/Lib/dataclasses.py
+++ b/Lib/dataclasses.py
@@ -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 = []
diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py
index 637c456..01e6684 100644
--- a/Lib/test/test_dataclasses.py
+++ b/Lib/test/test_dataclasses.py
@@ -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
index 0000000..700c974
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-10-10-07-07-31.gh-issue-96151.K9fwoq.rst
@@ -0,0 +1 @@
+Allow ``BUILTINS`` to be a valid field name for frozen dataclasses.