From 0a834c18cdafa5447d4436878e64aa7a4e4dc817 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Tue, 12 Feb 2019 04:11:48 -0800 Subject: [PATCH] bpo-35960: Fix dataclasses.field throwing away empty metadata. (GH-11815) (GH-11826) (cherry picked from commit b01786c8812c4cc24dd561b5941025bdd6f444c0) Co-authored-by: Christopher Hunt --- Lib/dataclasses.py | 2 +- Lib/test/test_dataclasses.py | 14 ++++++++++++-- .../2019-02-10-20-57-12.bpo-35960.bh-6Ja.rst | 2 ++ 3 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2019-02-10-20-57-12.bpo-35960.bh-6Ja.rst diff --git a/Lib/dataclasses.py b/Lib/dataclasses.py index 71d9896a1052..325b822d9f06 100644 --- a/Lib/dataclasses.py +++ b/Lib/dataclasses.py @@ -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 diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index ff6060c6d283..9c83459f09e7 100755 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -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'] diff --git a/Misc/NEWS.d/next/Library/2019-02-10-20-57-12.bpo-35960.bh-6Ja.rst b/Misc/NEWS.d/next/Library/2019-02-10-20-57-12.bpo-35960.bh-6Ja.rst new file mode 100644 index 000000000000..67135843877f --- /dev/null +++ b/Misc/NEWS.d/next/Library/2019-02-10-20-57-12.bpo-35960.bh-6Ja.rst @@ -0,0 +1,2 @@ +Fix :func:`dataclasses.field` throwing away empty mapping objects passed as +metadata. -- 2.47.3