(self, o: SequencePattern)
| 231 | return PatternType(narrowed_type, rest_type, {}) |
| 232 | |
| 233 | def visit_sequence_pattern(self, o: SequencePattern) -> PatternType: |
| 234 | # |
| 235 | # Step 1. Check for existence of a starred pattern |
| 236 | # |
| 237 | current_type = get_proper_type(self.type_context[-1]) |
| 238 | if not self.can_match_sequence(current_type): |
| 239 | return self.early_non_match() |
| 240 | |
| 241 | star_positions = [i for i, p in enumerate(o.patterns) if isinstance(p, StarredPattern)] |
| 242 | star_position: int | None = None |
| 243 | if len(star_positions) == 1: |
| 244 | star_position = star_positions[0] |
| 245 | elif len(star_positions) >= 2: |
| 246 | assert False, "Parser should prevent multiple starred patterns" |
| 247 | required_patterns = len(o.patterns) |
| 248 | if star_position is not None: |
| 249 | required_patterns -= 1 |
| 250 | |
| 251 | # |
| 252 | # Step 2. If we have a union, recurse and return the combined result |
| 253 | # |
| 254 | if isinstance(current_type, UnionType): |
| 255 | match_types: list[Type] = [] |
| 256 | rest_types: list[Type] = [] |
| 257 | captures_list: dict[Expression, list[Type]] = {} |
| 258 | |
| 259 | if star_position is not None: |
| 260 | star_pattern = o.patterns[star_position] |
| 261 | assert isinstance(star_pattern, StarredPattern) |
| 262 | star_expr = star_pattern.capture |
| 263 | else: |
| 264 | star_expr = None |
| 265 | |
| 266 | for t in current_type.items: |
| 267 | match_type, rest_type, captures = self.accept(o, t) |
| 268 | match_types.append(match_type) |
| 269 | rest_types.append(rest_type) |
| 270 | if not is_uninhabited(match_type): |
| 271 | for expr, typ in captures.items(): |
| 272 | p_typ = get_proper_type(typ) |
| 273 | if expr not in captures_list: |
| 274 | captures_list[expr] = [] |
| 275 | # Avoid adding in a list[Never] for empty list captures |
| 276 | if ( |
| 277 | expr == star_expr |
| 278 | and isinstance(p_typ, Instance) |
| 279 | and p_typ.type.fullname == "builtins.list" |
| 280 | and is_uninhabited(p_typ.args[0]) |
| 281 | ): |
| 282 | continue |
| 283 | captures_list[expr].append(typ) |
| 284 | |
| 285 | return PatternType( |
| 286 | make_simplified_union(match_types), |
| 287 | make_simplified_union(rest_types), |
| 288 | {expr: make_simplified_union(types) for expr, types in captures_list.items()}, |
| 289 | ) |
| 290 |
nothing calls this directly
no test coverage detected