Skip to content

Commit de3244c

Browse files
JukkaLilevkivskyi
authored andcommitted
Support TypedDicts with missing keys (total=False) (#3558)
* Basic support for TypedDicts with missing keys (total=False) Only the functional syntax is supported. * Support get(key, {}) and fix construction of partial typed dict * Fix subtyping of non-total typed dicts * Fix join with non-total typed dict * Fix meet with non-total typed dicts * Add serialization test case * Support TypedDict total keyword argument with class syntax * Attempt to fix Python 3.3 * Add minimal runtime `total` support to mypy_extensions There is no support for introspection of `total` yet. * Fix tests on pre-3.6 Python and improve introspection Make TypedDict `total` introspectable. * Fix lint * Fix problems caused by merge * Allow td['key'] even if td is not total * Fix lint * Add test case * Address review feedback * Update comment
1 parent 22a13c6 commit de3244c

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

mypy_extensions.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,18 @@ def _dict_new(cls, *args, **kwargs):
3030

3131

3232
def _typeddict_new(cls, _typename, _fields=None, **kwargs):
33+
total = kwargs.pop('total', True)
3334
if _fields is None:
3435
_fields = kwargs
3536
elif kwargs:
3637
raise TypeError("TypedDict takes either a dict or keyword arguments,"
3738
" but not both")
38-
return _TypedDictMeta(_typename, (), {'__annotations__': dict(_fields)})
39+
return _TypedDictMeta(_typename, (), {'__annotations__': dict(_fields),
40+
'__total__': total})
3941

4042

4143
class _TypedDictMeta(type):
42-
def __new__(cls, name, bases, ns):
44+
def __new__(cls, name, bases, ns, total=True):
4345
# Create new typed dict class object.
4446
# This method is called directly when TypedDict is subclassed,
4547
# or via _typeddict_new when TypedDict is instantiated. This way
@@ -59,6 +61,8 @@ def __new__(cls, name, bases, ns):
5961
for base in bases:
6062
anns.update(base.__dict__.get('__annotations__', {}))
6163
tp_dict.__annotations__ = anns
64+
if not hasattr(tp_dict, '__total__'):
65+
tp_dict.__total__ = total
6266
return tp_dict
6367

6468
__instancecheck__ = __subclasscheck__ = _check_fails

0 commit comments

Comments
 (0)