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

This commit is contained in:
Christopher Hunt 2019-02-12 06:50:49 -05:00 committed by Eric V. Smith
parent a31f4cc881
commit b01786c881
3 changed files with 15 additions and 3 deletions

View File

@ -241,7 +241,7 @@ class Field:
self.hash = hash
self.compare = compare
self.metadata = (_EMPTY_METADATA
if metadata is None or len(metadata) == 0 else
if metadata is None else
types.MappingProxyType(metadata))
self._field_type = None

View File

@ -1737,23 +1737,33 @@ class TestCase(unittest.TestCase):
i: int = field(metadata=0)
# Make sure an empty dict works.
d = {}
@dataclass
class C:
i: int = field(metadata={})
i: int = field(metadata=d)
self.assertFalse(fields(C)[0].metadata)
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,
'does not support item assignment'):
fields(C)[0].metadata['test'] = 3
# Make sure a non-empty dict works.
d = {'test': 10, 'bar': '42', 3: 'three'}
@dataclass
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(fields(C)[0].metadata['test'], 10)
self.assertEqual(fields(C)[0].metadata['bar'], '42')
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):
# Non-existent key.
fields(C)[0].metadata['baz']

View File

@ -0,0 +1,2 @@
Fix :func:`dataclasses.field` throwing away empty mapping objects passed as
metadata.