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 ext
(self, ir: ClassIR)
| 401 | super().add_attr(lvalue, stmt) |
| 402 | |
| 403 | def finalize(self, ir: ClassIR) -> None: |
| 404 | """Generate code to finish instantiating a dataclass. |
| 405 | |
| 406 | This works by replacing all of the attributes on the class |
| 407 | (which will be descriptors) with whatever they would be in a |
| 408 | non-extension class, calling dataclass, then switching them back. |
| 409 | |
| 410 | The resulting class is an extension class and instances of it do not |
| 411 | have a __dict__ (unless something else requires it). |
| 412 | All methods written explicitly in the source are compiled and |
| 413 | may be called through the vtable while the methods generated |
| 414 | by dataclasses are interpreted and may not be. |
| 415 | |
| 416 | (If we just called dataclass without doing this, it would think that all |
| 417 | of the descriptors for our attributes are default values and generate an |
| 418 | incorrect constructor. We need to do the switch so that dataclass gets the |
| 419 | appropriate defaults.) |
| 420 | """ |
| 421 | super().finalize(ir) |
| 422 | assert self.type_obj |
| 423 | add_dunders_to_non_ext_dict( |
| 424 | self.builder, self.non_ext, self.cdef.line, self.add_annotations_to_dict |
| 425 | ) |
| 426 | dec = self.builder.accept( |
| 427 | next(d for d in self.cdef.decorators if is_dataclass_decorator(d)) |
| 428 | ) |
| 429 | dataclass_type_val = self.builder.load_str(dataclass_type(self.cdef) or "unknown") |
| 430 | self.builder.call_c( |
| 431 | dataclass_sleight_of_hand, |
| 432 | [dec, self.type_obj, self.non_ext.dict, self.non_ext.anns, dataclass_type_val], |
| 433 | self.cdef.line, |
| 434 | ) |
| 435 | |
| 436 | |
| 437 | class AttrsClassBuilder(DataClassBuilder): |
nothing calls this directly
no test coverage detected