Create IR for a class definition. This can generate both extension (native) and non-extension classes. These are generated in very different ways. In the latter case we construct a Python type object at runtime by doing the equivalent of "type(name, bases, dict)" in IR. Extension
(builder: IRBuilder, cdef: ClassDef)
| 88 | |
| 89 | |
| 90 | def transform_class_def(builder: IRBuilder, cdef: ClassDef) -> None: |
| 91 | """Create IR for a class definition. |
| 92 | |
| 93 | This can generate both extension (native) and non-extension |
| 94 | classes. These are generated in very different ways. In the |
| 95 | latter case we construct a Python type object at runtime by doing |
| 96 | the equivalent of "type(name, bases, dict)" in IR. Extension |
| 97 | classes are defined via C structs that are generated later in |
| 98 | mypyc.codegen.emitclass. |
| 99 | |
| 100 | This is the main entry point to this module. |
| 101 | """ |
| 102 | if cdef.info not in builder.mapper.type_to_ir: |
| 103 | builder.error("Nested class definitions not supported", cdef.line) |
| 104 | return |
| 105 | |
| 106 | ir = builder.mapper.type_to_ir[cdef.info] |
| 107 | |
| 108 | # We do this check here because the base field of parent |
| 109 | # classes aren't necessarily populated yet at |
| 110 | # prepare_class_def time. |
| 111 | if any(ir.base_mro[i].base != ir.base_mro[i + 1] for i in range(len(ir.base_mro) - 1)): |
| 112 | builder.error("Multiple inheritance is not supported (except for traits)", cdef.line) |
| 113 | |
| 114 | if ir.allow_interpreted_subclasses: |
| 115 | for parent in ir.mro: |
| 116 | if not parent.allow_interpreted_subclasses: |
| 117 | builder.error( |
| 118 | 'Base class "{}" does not allow interpreted subclasses'.format( |
| 119 | parent.fullname |
| 120 | ), |
| 121 | cdef.line, |
| 122 | ) |
| 123 | |
| 124 | # Currently, we only create non-extension classes for classes that are |
| 125 | # decorated or inherit from Enum. Classes decorated with @trait do not |
| 126 | # apply here, and are handled in a different way. |
| 127 | if ir.is_ext_class: |
| 128 | cls_type = dataclass_type(cdef) |
| 129 | if cls_type is None: |
| 130 | cls_builder: ClassBuilder = ExtClassBuilder(builder, cdef) |
| 131 | elif cls_type in ["dataclasses", "attr-auto"]: |
| 132 | cls_builder = DataClassBuilder(builder, cdef) |
| 133 | elif cls_type == "attr": |
| 134 | cls_builder = AttrsClassBuilder(builder, cdef) |
| 135 | else: |
| 136 | raise ValueError(cls_type) |
| 137 | else: |
| 138 | cls_builder = NonExtClassBuilder(builder, cdef) |
| 139 | |
| 140 | # Set up class body context so that intra-class ClassVar references |
| 141 | # (e.g. C = A | B where A is defined earlier in the same class) can be |
| 142 | # resolved from the class being built instead of module globals. |
| 143 | builder.class_body_classvars = {} |
| 144 | builder.class_body_obj = cls_builder.class_body_obj() |
| 145 | builder.class_body_ir = ir |
| 146 | |
| 147 | for stmt in cdef.defs.body: |
no test coverage detected
searching dependent graphs…