Commit b01786c8 authored by Christopher Hunt's avatar Christopher Hunt Committed by Eric V. Smith

bpo-35960: Fix dataclasses.field throwing away empty metadata. (GH-11815)

parent a31f4cc8
...@@ -241,7 +241,7 @@ class Field: ...@@ -241,7 +241,7 @@ class Field:
self.hash = hash self.hash = hash
self.compare = compare self.compare = compare
self.metadata = (_EMPTY_METADATA self.metadata = (_EMPTY_METADATA
if metadata is None or len(metadata) == 0 else if metadata is None else
types.MappingProxyType(metadata)) types.MappingProxyType(metadata))
self._field_type = None self._field_type = None
......
...@@ -1737,23 +1737,33 @@ class TestCase(unittest.TestCase): ...@@ -1737,23 +1737,33 @@ class TestCase(unittest.TestCase):
i: int = field(metadata=0) i: int = field(metadata=0)
# Make sure an empty dict works. # Make sure an empty dict works.
d = {}
@dataclass @dataclass
class C: class C:
i: int = field(metadata={}) i: int = field(metadata=d)
self.assertFalse(fields(C)[0].metadata) self.assertFalse(fields(C)[0].metadata)
self.assertEqual(len(fields(C)[0].metadata), 0) self.assertEqual(len(fields(C)[0].metadata), 0)
# Update should work (see bpo-35960).
d['foo'] = 1
self.assertEqual(len(fields(C)[0].metadata), 1)
self.assertEqual(fields(C)[0].metadata['foo'], 1)
with self.assertRaisesRegex(TypeError, with self.assertRaisesRegex(TypeError,
'does not support item assignment'): 'does not support item assignment'):
fields(C)[0].metadata['test'] = 3 fields(C)[0].metadata['test'] = 3
# Make sure a non-empty dict works. # Make sure a non-empty dict works.
d = {'test': 10, 'bar': '42', 3: 'three'}
@dataclass @dataclass
class C: class C:
i: int = field(metadata={'test': 10, 'bar': '42', 3: 'three'}) i: int = field(metadata=d)
self.assertEqual(len(fields(C)[0].metadata), 3) self.assertEqual(len(fields(C)[0].metadata), 3)
self.assertEqual(fields(C)[0].metadata['test'], 10) self.assertEqual(fields(C)[0].metadata['test'], 10)
self.assertEqual(fields(C)[0].metadata['bar'], '42') self.assertEqual(fields(C)[0].metadata['bar'], '42')
self.assertEqual(fields(C)[0].metadata[3], 'three') self.assertEqual(fields(C)[0].metadata[3], 'three')
# Update should work.
d['foo'] = 1
self.assertEqual(len(fields(C)[0].metadata), 4)
self.assertEqual(fields(C)[0].metadata['foo'], 1)
with self.assertRaises(KeyError): with self.assertRaises(KeyError):
# Non-existent key. # Non-existent key.
fields(C)[0].metadata['baz'] fields(C)[0].metadata['baz']
......
Fix :func:`dataclasses.field` throwing away empty mapping objects passed as
metadata.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment