@@ -6391,7 +6391,8 @@ def conditional_types_for_iterable(
63916391 ) -> tuple [Type , Type ]:
63926392 """
63936393 Narrows the type of `iterable_type` based on the type of `item_type`.
6394- For now, we only support narrowing unions of TypedDicts based on left operand being literal string(s).
6394+ For now, we only support narrowing unions of TypedDicts, and TypeVars with TypedDict
6395+ bounds, based on left operand being literal string(s).
63956396 """
63966397 if_types : list [Type ] = []
63976398 else_types : list [Type ] = []
@@ -6405,18 +6406,19 @@ def conditional_types_for_iterable(
64056406 item_str_literals = try_getting_str_literals_from_type (item_type )
64066407
64076408 for possible_iterable_type in possible_iterable_types :
6408- if item_str_literals and isinstance (possible_iterable_type , TypedDictType ):
6409+ bound = (
6410+ get_proper_type (possible_iterable_type .upper_bound )
6411+ if isinstance (possible_iterable_type , TypeVarType )
6412+ else possible_iterable_type
6413+ )
6414+
6415+ if item_str_literals and isinstance (bound , TypedDictType ):
64096416 for key in item_str_literals :
6410- if key in possible_iterable_type .required_keys :
6417+ if key in bound .required_keys :
64116418 if_types .append (possible_iterable_type )
64126419 elif (
6413- key in possible_iterable_type .items
6414- and not isinstance (possible_iterable_type .items [key ], UninhabitedType )
6415- ) or (
6416- key not in possible_iterable_type .items
6417- and not possible_iterable_type .is_closed
6418- and not possible_iterable_type .is_final
6419- ):
6420+ key in bound .items and not isinstance (bound .items [key ], UninhabitedType )
6421+ ) or (key not in bound .items and not bound .is_closed and not bound .is_final ):
64206422 if_types .append (possible_iterable_type )
64216423 else_types .append (possible_iterable_type )
64226424 else :
0 commit comments