Type check a tuple expression.
(self, e: TupleExpr)
| 5271 | return len(expr.items) == len(ctx.items) and ctx_unpack_index == expr_star_index |
| 5272 | |
| 5273 | def visit_tuple_expr(self, e: TupleExpr) -> Type: |
| 5274 | """Type check a tuple expression.""" |
| 5275 | # Try to determine type context for type inference. |
| 5276 | type_context = get_proper_type(self.type_context[-1]) |
| 5277 | type_context_items = None |
| 5278 | if isinstance(type_context, UnionType): |
| 5279 | tuples_in_context = [ |
| 5280 | t |
| 5281 | for t in get_proper_types(type_context.items) |
| 5282 | if (isinstance(t, TupleType) and self.tuple_context_matches(e, t)) |
| 5283 | or is_named_instance(t, TUPLE_LIKE_INSTANCE_NAMES) |
| 5284 | ] |
| 5285 | if len(tuples_in_context) == 1: |
| 5286 | type_context = tuples_in_context[0] |
| 5287 | else: |
| 5288 | # There are either no relevant tuples in the Union, or there is |
| 5289 | # more than one. Either way, we can't decide on a context. |
| 5290 | pass |
| 5291 | |
| 5292 | if isinstance(type_context, TupleType) and self.tuple_context_matches(e, type_context): |
| 5293 | type_context_items = type_context.items |
| 5294 | elif type_context and is_named_instance(type_context, TUPLE_LIKE_INSTANCE_NAMES): |
| 5295 | assert isinstance(type_context, Instance) |
| 5296 | if type_context.args: |
| 5297 | type_context_items = [type_context.args[0]] * len(e.items) |
| 5298 | # NOTE: it's possible for the context to have a different |
| 5299 | # number of items than e. In that case we use those context |
| 5300 | # items that match a position in e, and we'll worry about type |
| 5301 | # mismatches later. |
| 5302 | |
| 5303 | unpack_in_context = False |
| 5304 | if type_context_items is not None: |
| 5305 | unpack_in_context = find_unpack_in_list(type_context_items) is not None |
| 5306 | seen_unpack_in_items = False |
| 5307 | allow_precise_tuples = ( |
| 5308 | unpack_in_context or PRECISE_TUPLE_TYPES in self.chk.options.enable_incomplete_feature |
| 5309 | ) |
| 5310 | |
| 5311 | # Infer item types. Give up if there's a star expression |
| 5312 | # that's not a Tuple. |
| 5313 | items: list[Type] = [] |
| 5314 | j = 0 # Index into type_context_items; irrelevant if type_context_items is none |
| 5315 | for i in range(len(e.items)): |
| 5316 | item = e.items[i] |
| 5317 | if isinstance(item, StarExpr): |
| 5318 | # Special handling for star expressions. |
| 5319 | # TODO: If there's a context, and item.expr is a |
| 5320 | # TupleExpr, flatten it, so we can benefit from the |
| 5321 | # context? Counterargument: Why would anyone write |
| 5322 | # (1, *(2, 3)) instead of (1, 2, 3) except in a test? |
| 5323 | if unpack_in_context: |
| 5324 | # Note: this logic depends on full structure match in tuple_context_matches(). |
| 5325 | assert type_context_items |
| 5326 | ctx_item = type_context_items[j] |
| 5327 | assert isinstance(ctx_item, UnpackType) |
| 5328 | ctx = ctx_item.type |
| 5329 | else: |
| 5330 | ctx = None |
nothing calls this directly
no test coverage detected