Analyze base class types. Return None if some definition was incomplete. Otherwise, return a tuple with these items: * List of (analyzed type, original expression) tuples * Boolean indicating whether one of the bases had a semantic analysis error
(
self, base_type_exprs: list[Expression]
)
| 2588 | return None |
| 2589 | |
| 2590 | def analyze_base_classes( |
| 2591 | self, base_type_exprs: list[Expression] |
| 2592 | ) -> tuple[list[tuple[ProperType, Expression]], bool] | None: |
| 2593 | """Analyze base class types. |
| 2594 | |
| 2595 | Return None if some definition was incomplete. Otherwise, return a tuple |
| 2596 | with these items: |
| 2597 | |
| 2598 | * List of (analyzed type, original expression) tuples |
| 2599 | * Boolean indicating whether one of the bases had a semantic analysis error |
| 2600 | """ |
| 2601 | is_error = False |
| 2602 | bases = [] |
| 2603 | for base_expr in base_type_exprs: |
| 2604 | if ( |
| 2605 | isinstance(base_expr, RefExpr) |
| 2606 | and base_expr.fullname in TYPED_NAMEDTUPLE_NAMES + TPDICT_NAMES |
| 2607 | ) or ( |
| 2608 | isinstance(base_expr, CallExpr) |
| 2609 | and isinstance(base_expr.callee, RefExpr) |
| 2610 | and base_expr.callee.fullname in TPDICT_NAMES |
| 2611 | ): |
| 2612 | # Ignore magic bases for now. |
| 2613 | # For example: |
| 2614 | # class Foo(TypedDict): ... # RefExpr |
| 2615 | # class Foo(NamedTuple): ... # RefExpr |
| 2616 | # class Foo(TypedDict("Foo", {"a": int})): ... # CallExpr |
| 2617 | continue |
| 2618 | |
| 2619 | try: |
| 2620 | base = self.expr_to_analyzed_type( |
| 2621 | base_expr, allow_placeholder=True, allow_type_any=True |
| 2622 | ) |
| 2623 | except TypeTranslationError: |
| 2624 | name = self.get_name_repr_of_expr(base_expr) |
| 2625 | if isinstance(base_expr, CallExpr): |
| 2626 | msg = "Unsupported dynamic base class" |
| 2627 | else: |
| 2628 | msg = "Invalid base class" |
| 2629 | if name: |
| 2630 | msg += f' "{name}"' |
| 2631 | self.fail(msg, base_expr) |
| 2632 | is_error = True |
| 2633 | continue |
| 2634 | if base is None: |
| 2635 | return None |
| 2636 | base = get_proper_type(base) |
| 2637 | bases.append((base, base_expr)) |
| 2638 | return bases, is_error |
| 2639 | |
| 2640 | def configure_base_classes( |
| 2641 | self, defn: ClassDef, bases: list[tuple[ProperType, Expression]] |
no test coverage detected