]> granicus.if.org Git - python/commitdiff
bpo-35960: Fix dataclasses.field throwing away empty metadata. (GH-11815)
authorChristopher Hunt <chrahunt@gmail.com>
Tue, 12 Feb 2019 11:50:49 +0000 (06:50 -0500)
committerEric V. Smith <ericvsmith@users.noreply.github.com>
Tue, 12 Feb 2019 11:50:49 +0000 (06:50 -0500)
Lib/dataclasses.py
Lib/test/test_dataclasses.py
Misc/NEWS.d/next/Library/2019-02-10-20-57-12.bpo-35960.bh-6Ja.rst [new file with mode: 0644]

index 71d9896a10524a9e1265fc5aa058edcad6e9d59a..325b822d9f06f110127e252015d6cc80c95899a0 100644 (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
 
index ff6060c6d2838acf09e3a0519104a920aadf924a..9c83459f09e79714238b1415df0c15ebe818c0db 100755 (executable)
@@ -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 (file)
index 0000000..6713584
--- /dev/null
@@ -0,0 +1,2 @@
+Fix :func:`dataclasses.field` throwing away empty mapping objects passed as
+metadata.