MCPcopy Index your code
hub / github.com/python/mypy / visit_get_attr

Method visit_get_attr

mypyc/codegen/emitfunc.py:397–470  ·  view source on GitHub ↗
(self, op: GetAttr)

Source from the content-addressed store, hash-verified

395 return f"({cast}{obj})->{self.emitter.attr(op.attr)}"
396
397 def visit_get_attr(self, op: GetAttr) -> None:
398 if op.allow_error_value:
399 self.get_attr_with_allow_error_value(op)
400 return
401 dest = self.reg(op)
402 obj = self.reg(op.obj)
403 rtype = op.class_type
404 cl = rtype.class_ir
405 attr_rtype, decl_cl = cl.attr_details(op.attr)
406 prefer_method = cl.is_trait and attr_rtype.error_overlap
407 if cl.get_method(op.attr, prefer_method=prefer_method):
408 # Properties are essentially methods, so use vtable access for them
409 # (except for non-ext classes, which have no vtable — see emit_method_call).
410 if not cl.is_ext_class or cl.is_method_final(op.attr):
411 self.emit_method_call(f"{dest} = ", op.obj, op.attr, [])
412 else:
413 version = "_TRAIT" if cl.is_trait else ""
414 self.emit_line(
415 "%s = CPY_GET_ATTR%s(%s, %s, %d, %s, %s); /* %s */"
416 % (
417 dest,
418 version,
419 obj,
420 self.emitter.type_struct_name(rtype.class_ir),
421 rtype.getter_index(op.attr),
422 rtype.struct_name(self.names),
423 self.ctype(rtype.attr_type(op.attr)),
424 op.attr,
425 )
426 )
427 else:
428 # Otherwise, use direct or offset struct access.
429 attr_expr = self.get_attr_expr(obj, op, decl_cl)
430 self.emitter.emit_line(f"{dest} = {attr_expr};")
431 always_defined = cl.is_always_defined(op.attr)
432 merged_branch = None
433 if not always_defined:
434 self.emitter.emit_undefined_attr_check(
435 attr_rtype, dest, "==", obj, op.attr, cl, unlikely=True
436 )
437 branch = self.next_branch()
438 if branch is not None:
439 if (
440 branch.value is op
441 and branch.op == Branch.IS_ERROR
442 and branch.traceback_entry is not None
443 and not branch.negated
444 ):
445 # Generate code for the following branch here to avoid
446 # redundant branches in the generated code.
447 self.emit_attribute_error(branch, cl.name, op.attr)
448 self.emit_line("goto %s;" % self.label(branch.true))
449 merged_branch = branch
450 self.emitter.emit_line("}")
451 if not merged_branch:
452 exc_class = "PyExc_AttributeError"
453 self.emitter.emit_line(
454 'PyErr_SetString({}, "attribute {} of {} undefined");'.format(

Callers

nothing calls this directly

Calls 15

regMethod · 0.95
emit_method_callMethod · 0.95
emit_lineMethod · 0.95
ctypeMethod · 0.95
get_attr_exprMethod · 0.95
next_branchMethod · 0.95
emit_attribute_errorMethod · 0.95
labelMethod · 0.95
reprFunction · 0.85
attr_detailsMethod · 0.80
is_method_finalMethod · 0.80

Tested by

no test coverage detected