Skip to content

Commit

Permalink
bpo-35960: Fix dataclasses.field throwing away empty metadata. (GH-11815
Browse files Browse the repository at this point in the history
) (GH-11826)

(cherry picked from commit b01786c)

Co-authored-by: Christopher Hunt <chrahunt@gmail.com>
  • Loading branch information
2 people authored and ericvsmith committed Feb 12, 2019
1 parent 58f05ce commit 0a834c1
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 3 deletions.
2 changes: 1 addition & 1 deletion Lib/dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ def __init__(self, default, default_factory, init, repr, hash, compare,
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

Expand Down
14 changes: 12 additions & 2 deletions Lib/test/test_dataclasses.py
Original file line number Diff line number Diff line change
Expand Up @@ -1737,23 +1737,33 @@ class C:
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']
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix :func:`dataclasses.field` throwing away empty mapping objects passed as
metadata.

0 comments on commit 0a834c1

Please sign in to comment.