(cl: ClassIR, attr: str, rtype: RType, emitter: Emitter)
| 1146 | |
| 1147 | |
| 1148 | def generate_getter(cl: ClassIR, attr: str, rtype: RType, emitter: Emitter) -> None: |
| 1149 | attr_field = emitter.attr(attr) |
| 1150 | emitter.emit_line("static PyObject *") |
| 1151 | emitter.emit_line( |
| 1152 | "{}({} *self, void *closure)".format( |
| 1153 | getter_name(cl, attr, emitter.names), cl.struct_name(emitter.names) |
| 1154 | ) |
| 1155 | ) |
| 1156 | emitter.emit_line("{") |
| 1157 | attr_expr = f"self->{attr_field}" |
| 1158 | |
| 1159 | # HACK: Don't consider refcounted values as always defined, since it's possible to |
| 1160 | # access uninitialized values via 'gc.get_objects()'. Accessing non-refcounted |
| 1161 | # values is benign. |
| 1162 | always_defined = cl.is_always_defined(attr) and not rtype.is_refcounted |
| 1163 | |
| 1164 | if not always_defined: |
| 1165 | emitter.emit_undefined_attr_check(rtype, attr_expr, "==", "self", attr, cl, unlikely=True) |
| 1166 | emitter.emit_line("PyErr_SetString(PyExc_AttributeError,") |
| 1167 | emitter.emit_line(f' "attribute {repr(attr)} of {repr(cl.name)} undefined");') |
| 1168 | emitter.emit_line("return NULL;") |
| 1169 | emitter.emit_line("}") |
| 1170 | emitter.emit_inc_ref(f"self->{attr_field}", rtype) |
| 1171 | emitter.emit_box(f"self->{attr_field}", "retval", rtype, declare_dest=True) |
| 1172 | emitter.emit_line("return retval;") |
| 1173 | emitter.emit_line("}") |
| 1174 | |
| 1175 | |
| 1176 | def generate_setter(cl: ClassIR, attr: str, rtype: RType, emitter: Emitter) -> None: |
no test coverage detected
searching dependent graphs…