Set up base classes. This computes several attributes on the corresponding TypeInfo defn.info related to the base classes: defn.info.bases, defn.info.mro, and miscellaneous others (at least tuple_type, fallback_to_any, and is_enum.)
(
self, defn: ClassDef, bases: list[tuple[ProperType, Expression]]
)
| 2638 | return bases, is_error |
| 2639 | |
| 2640 | def configure_base_classes( |
| 2641 | self, defn: ClassDef, bases: list[tuple[ProperType, Expression]] |
| 2642 | ) -> None: |
| 2643 | """Set up base classes. |
| 2644 | |
| 2645 | This computes several attributes on the corresponding TypeInfo defn.info |
| 2646 | related to the base classes: defn.info.bases, defn.info.mro, and |
| 2647 | miscellaneous others (at least tuple_type, fallback_to_any, and is_enum.) |
| 2648 | """ |
| 2649 | base_types: list[Instance] = [] |
| 2650 | info = defn.info |
| 2651 | |
| 2652 | for base, base_expr in bases: |
| 2653 | if isinstance(base, TupleType): |
| 2654 | actual_base = self.configure_tuple_base_class(defn, base) |
| 2655 | base_types.append(actual_base) |
| 2656 | elif isinstance(base, Instance): |
| 2657 | if base.type.is_newtype: |
| 2658 | self.fail('Cannot subclass "NewType"', defn) |
| 2659 | base_types.append(base) |
| 2660 | elif isinstance(base, AnyType): |
| 2661 | if self.options.disallow_subclassing_any: |
| 2662 | if isinstance(base_expr, (NameExpr, MemberExpr)): |
| 2663 | msg = f'Class cannot subclass "{base_expr.name}" (has type "Any")' |
| 2664 | else: |
| 2665 | msg = 'Class cannot subclass value of type "Any"' |
| 2666 | self.fail(msg, base_expr) |
| 2667 | info.fallback_to_any = True |
| 2668 | elif isinstance(base, TypedDictType): |
| 2669 | base_types.append(base.fallback) |
| 2670 | else: |
| 2671 | msg = "Invalid base class" |
| 2672 | name = self.get_name_repr_of_expr(base_expr) |
| 2673 | if name: |
| 2674 | msg += f' "{name}"' |
| 2675 | self.fail(msg, base_expr) |
| 2676 | info.fallback_to_any = True |
| 2677 | if self.options.disallow_any_unimported and has_any_from_unimported_type(base): |
| 2678 | if isinstance(base_expr, (NameExpr, MemberExpr)): |
| 2679 | prefix = f"Base type {base_expr.name}" |
| 2680 | else: |
| 2681 | prefix = "Base type" |
| 2682 | self.msg.unimported_type_becomes_any(prefix, base, base_expr) |
| 2683 | check_for_explicit_any( |
| 2684 | base, self.options, self.is_typeshed_stub_file, self.msg, context=base_expr |
| 2685 | ) |
| 2686 | |
| 2687 | # Add 'object' as implicit base if there is no other base class. |
| 2688 | if not base_types and defn.fullname != "builtins.object": |
| 2689 | base_types.append(self.object_type()) |
| 2690 | |
| 2691 | info.bases = base_types |
| 2692 | |
| 2693 | # Calculate the MRO. |
| 2694 | if not self.verify_base_classes(defn): |
| 2695 | self.set_dummy_mro(defn.info) |
| 2696 | return |
| 2697 | if not self.verify_duplicate_base_classes(defn): |
no test coverage detected