def finalize(self, ir: ClassIR) -> None: """Generate code to finish instantiating a dataclass. This works by replacing all of the attributes on the class (which will be descriptors) with whatever they would be in a non-extension class, calling dataclass, then switching them back. The resulting class is an extension class and instances of it do not have a __dict__ (unless something else requires it). All methods written explicitly in the source are compiled and may be called through the vtable while the methods generated by dataclasses are interpreted and may not be. (If we just called dataclass without doing this, it would think that all of the descriptors for our attributes are default values and generate an incorrect constructor. We need to do the switch so that dataclass gets the appropriate defaults.) """ super().finalize(ir) assert self.type_obj add_dunders_to_non_ext_dict(self.builder, self.non_ext, self.cdef.line, self.add_annotations_to_dict) dec = self.builder.accept( next(d for d in self.cdef.decorators if is_dataclass_decorator(d))) self.builder.call_c( dataclass_sleight_of_hand, [dec, self.type_obj, self.non_ext.dict, self.non_ext.anns], self.cdef.line)
def dataclass_finalize( builder: IRBuilder, cdef: ClassDef, non_ext: NonExtClassInfo, type_obj: Value) -> None: """Generate code to finish instantiating a dataclass. This works by replacing all of the attributes on the class (which will be descriptors) with whatever they would be in a non-extension class, calling dataclass, then switching them back. The resulting class is an extension class and instances of it do not have a __dict__ (unless something else requires it). All methods written explicitly in the source are compiled and may be called through the vtable while the methods generated by dataclasses are interpreted and may not be. (If we just called dataclass without doing this, it would think that all of the descriptors for our attributes are default values and generate an incorrect constructor. We need to do the switch so that dataclass gets the appropriate defaults.) """ finish_non_ext_dict(builder, non_ext, cdef.line) dec = builder.accept(next(d for d in cdef.decorators if is_dataclass_decorator(d))) builder.call_c( dataclass_sleight_of_hand, [dec, type_obj, non_ext.dict, non_ext.anns], cdef.line)