bpo-42059: Fix required/optional keys for TypedDict(..., total=False) (GH-22736)
This commit is contained in:
parent
a658287179
commit
67b769f515
|
@ -3895,10 +3895,14 @@ class TypedDictTests(BaseTestCase):
|
||||||
self.assertEqual(D(), {})
|
self.assertEqual(D(), {})
|
||||||
self.assertEqual(D(x=1), {'x': 1})
|
self.assertEqual(D(x=1), {'x': 1})
|
||||||
self.assertEqual(D.__total__, False)
|
self.assertEqual(D.__total__, False)
|
||||||
|
self.assertEqual(D.__required_keys__, frozenset())
|
||||||
|
self.assertEqual(D.__optional_keys__, {'x'})
|
||||||
|
|
||||||
self.assertEqual(Options(), {})
|
self.assertEqual(Options(), {})
|
||||||
self.assertEqual(Options(log_level=2), {'log_level': 2})
|
self.assertEqual(Options(log_level=2), {'log_level': 2})
|
||||||
self.assertEqual(Options.__total__, False)
|
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):
|
def test_optional_keys(self):
|
||||||
class Point2Dor3D(Point2D, total=False):
|
class Point2Dor3D(Point2D, total=False):
|
||||||
|
|
|
@ -2043,14 +2043,14 @@ def TypedDict(typename, fields=None, /, *, total=True, **kwargs):
|
||||||
raise TypeError("TypedDict takes either a dict or keyword arguments,"
|
raise TypeError("TypedDict takes either a dict or keyword arguments,"
|
||||||
" but not both")
|
" but not both")
|
||||||
|
|
||||||
ns = {'__annotations__': dict(fields), '__total__': total}
|
ns = {'__annotations__': dict(fields)}
|
||||||
try:
|
try:
|
||||||
# Setting correct module is necessary to make typed dict classes pickleable.
|
# Setting correct module is necessary to make typed dict classes pickleable.
|
||||||
ns['__module__'] = sys._getframe(1).f_globals.get('__name__', '__main__')
|
ns['__module__'] = sys._getframe(1).f_globals.get('__name__', '__main__')
|
||||||
except (AttributeError, ValueError):
|
except (AttributeError, ValueError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
return _TypedDictMeta(typename, (), ns)
|
return _TypedDictMeta(typename, (), ns, total=total)
|
||||||
|
|
||||||
_TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {})
|
_TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {})
|
||||||
TypedDict.__mro_entries__ = lambda bases: (_TypedDict,)
|
TypedDict.__mro_entries__ = lambda bases: (_TypedDict,)
|
||||||
|
|
|
@ -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.
|
Loading…
Reference in New Issue