]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-42059: Fix required/optional keys for TypedDict(..., total=False) (GH-22736)...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 14 Dec 2020 22:33:27 +0000 (14:33 -0800)
committerGitHub <noreply@github.com>
Mon, 14 Dec 2020 22:33:27 +0000 (14:33 -0800)
(cherry picked from commit 67b769f5157c9dad1c7dd6b24e067b9fdab5b35d)

Co-authored-by: Alex Grönholm <alex.gronholm@nextday.fi>
Lib/test/test_typing.py
Lib/typing.py
Misc/NEWS.d/next/Library/2020-10-17-12-42-08.bpo-42059.ZGMZ3D.rst [new file with mode: 0644]

index 04dd6df6a9cc40d19b5ebf3ddee2e8ad03756501..3b3aa29de7221de5202d2e391f624ab8b5e0ad2b 100644 (file)
@@ -3891,10 +3891,14 @@ class TypedDictTests(BaseTestCase):
         self.assertEqual(D(), {})
         self.assertEqual(D(x=1), {'x': 1})
         self.assertEqual(D.__total__, False)
+        self.assertEqual(D.__required_keys__, frozenset())
+        self.assertEqual(D.__optional_keys__, {'x'})
 
         self.assertEqual(Options(), {})
         self.assertEqual(Options(log_level=2), {'log_level': 2})
         self.assertEqual(Options.__total__, False)
+        self.assertEqual(Options.__required_keys__, frozenset())
+        self.assertEqual(Options.__optional_keys__, {'log_level', 'log_path'})
 
     def test_optional_keys(self):
         class Point2Dor3D(Point2D, total=False):
index 1d6584db5afb28d521cb157b9904ebbc32a364b1..81e4a2fa403b9a1e980b5b1af2beddd7438590f8 100644 (file)
@@ -1987,14 +1987,14 @@ def TypedDict(typename, fields=None, /, *, total=True, **kwargs):
         raise TypeError("TypedDict takes either a dict or keyword arguments,"
                         " but not both")
 
-    ns = {'__annotations__': dict(fields), '__total__': total}
+    ns = {'__annotations__': dict(fields)}
     try:
         # Setting correct module is necessary to make typed dict classes pickleable.
         ns['__module__'] = sys._getframe(1).f_globals.get('__name__', '__main__')
     except (AttributeError, ValueError):
         pass
 
-    return _TypedDictMeta(typename, (), ns)
+    return _TypedDictMeta(typename, (), ns, total=total)
 
 _TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {})
 TypedDict.__mro_entries__ = lambda bases: (_TypedDict,)
diff --git a/Misc/NEWS.d/next/Library/2020-10-17-12-42-08.bpo-42059.ZGMZ3D.rst b/Misc/NEWS.d/next/Library/2020-10-17-12-42-08.bpo-42059.ZGMZ3D.rst
new file mode 100644 (file)
index 0000000..3f18824
--- /dev/null
@@ -0,0 +1 @@
+:class:`typing.TypedDict` types created using the alternative call-style syntax now correctly respect the ``total`` keyword argument when setting their ``__required_keys__`` and ``__optional_keys__`` class attributes.