mirror of
https://github.com/python/cpython.git
synced 2025-07-19 17:25:54 +00:00
[3.11] gh-96151: Use a private name for passing builtins to dataclass. This now allows for a field named BUILTIN (gh-98143) (gh-98900)
gh-96151: Use a private name for passing builtins to dataclass. This now allows for a field named BUILTIN (gh-98143)
(cherry picked from commit 29f98b46b7
)
Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com>
Co-authored-by: Shantanu <12621235+hauntsaninja@users.noreply.github.com>
This commit is contained in:
parent
57dd11038f
commit
ca24e496ba
3 changed files with 13 additions and 5 deletions
|
@ -412,13 +412,11 @@ def _recursive_repr(user_function):
|
||||||
|
|
||||||
def _create_fn(name, args, body, *, globals=None, locals=None,
|
def _create_fn(name, args, body, *, globals=None, locals=None,
|
||||||
return_type=MISSING):
|
return_type=MISSING):
|
||||||
# Note that we mutate locals when exec() is called. Caller
|
# Note that we may mutate locals. Callers beware!
|
||||||
# beware! The only callers are internal to this module, so no
|
# The only callers are internal to this module, so no
|
||||||
# worries about external callers.
|
# worries about external callers.
|
||||||
if locals is None:
|
if locals is None:
|
||||||
locals = {}
|
locals = {}
|
||||||
if 'BUILTINS' not in locals:
|
|
||||||
locals['BUILTINS'] = builtins
|
|
||||||
return_annotation = ''
|
return_annotation = ''
|
||||||
if return_type is not MISSING:
|
if return_type is not MISSING:
|
||||||
locals['_return_type'] = return_type
|
locals['_return_type'] = return_type
|
||||||
|
@ -444,7 +442,7 @@ def _field_assign(frozen, name, value, self_name):
|
||||||
# self_name is what "self" is called in this function: don't
|
# self_name is what "self" is called in this function: don't
|
||||||
# hard-code "self", since that might be a field name.
|
# hard-code "self", since that might be a field name.
|
||||||
if frozen:
|
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}'
|
return f'{self_name}.{name}={value}'
|
||||||
|
|
||||||
|
|
||||||
|
@ -551,6 +549,7 @@ def _init_fn(fields, std_fields, kw_only_fields, frozen, has_post_init,
|
||||||
locals.update({
|
locals.update({
|
||||||
'MISSING': MISSING,
|
'MISSING': MISSING,
|
||||||
'_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY,
|
'_HAS_DEFAULT_FACTORY': _HAS_DEFAULT_FACTORY,
|
||||||
|
'__dataclass_builtins_object__': object,
|
||||||
})
|
})
|
||||||
|
|
||||||
body_lines = []
|
body_lines = []
|
||||||
|
|
|
@ -231,6 +231,14 @@ class TestCase(unittest.TestCase):
|
||||||
c = C('foo')
|
c = C('foo')
|
||||||
self.assertEqual(c.object, '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):
|
def test_field_named_like_builtin(self):
|
||||||
# Attribute names can shadow built-in names
|
# Attribute names can shadow built-in names
|
||||||
# since code generation is used.
|
# since code generation is used.
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Allow ``BUILTINS`` to be a valid field name for frozen dataclasses.
|
Loading…
Add table
Add a link
Reference in a new issue