(self, o: MappingPattern)
| 486 | return PatternType(self.type_context[-1], UninhabitedType(), captures) |
| 487 | |
| 488 | def visit_mapping_pattern(self, o: MappingPattern) -> PatternType: |
| 489 | current_type = get_proper_type(self.type_context[-1]) |
| 490 | can_match = True |
| 491 | captures: dict[Expression, Type] = {} |
| 492 | for key, value in zip(o.keys, o.values): |
| 493 | inner_type = self.get_mapping_item_type(o, current_type, key) |
| 494 | if inner_type is None: |
| 495 | can_match = False |
| 496 | inner_type = self.chk.named_type("builtins.object") |
| 497 | pattern_type = self.accept(value, inner_type) |
| 498 | if is_uninhabited(pattern_type.type): |
| 499 | can_match = False |
| 500 | else: |
| 501 | self.update_type_map(captures, pattern_type.captures) |
| 502 | |
| 503 | if o.rest is not None: |
| 504 | mapping = self.chk.named_type("typing.Mapping") |
| 505 | if is_subtype(current_type, mapping) and isinstance(current_type, Instance): |
| 506 | mapping_inst = map_instance_to_supertype(current_type, mapping.type) |
| 507 | dict_typeinfo = self.chk.lookup_typeinfo("builtins.dict") |
| 508 | rest_type = Instance(dict_typeinfo, mapping_inst.args) |
| 509 | else: |
| 510 | object_type = self.chk.named_type("builtins.object") |
| 511 | rest_type = self.chk.named_generic_type( |
| 512 | "builtins.dict", [object_type, object_type] |
| 513 | ) |
| 514 | |
| 515 | captures[o.rest] = rest_type |
| 516 | |
| 517 | else_type = current_type |
| 518 | if can_match: |
| 519 | # We can't narrow the type here, as Mapping key is invariant. |
| 520 | new_type = self.type_context[-1] |
| 521 | if not o.keys: |
| 522 | # Match cannot be refuted, so narrow the remaining type |
| 523 | mapping = self.chk.named_type("typing.Mapping") |
| 524 | if_type, else_type = self.chk.conditional_types_with_intersection( |
| 525 | current_type, |
| 526 | [TypeRange(mapping, is_upper_bound=False)], |
| 527 | o, |
| 528 | default=current_type, |
| 529 | ) |
| 530 | if not isinstance(current_type, AnyType): |
| 531 | new_type = if_type |
| 532 | else: |
| 533 | new_type = UninhabitedType() |
| 534 | return PatternType(new_type, else_type, captures) |
| 535 | |
| 536 | def get_mapping_item_type( |
| 537 | self, pattern: MappingPattern, mapping_type: Type, key: Expression |
nothing calls this directly
no test coverage detected