MCPcopy
hub / github.com/python/mypy / generate_setup_for_class

Function generate_setup_for_class

mypyc/codegen/emitclass.py:608–670  ·  view source on GitHub ↗

Generate a native function that allocates an instance of a class.

(
    cl: ClassIR,
    defaults_fn: FuncIR | None,
    vtable_name: str,
    shadow_vtable_name: str | None,
    emitter: Emitter,
)

Source from the content-addressed store, hash-verified

606
607
608def generate_setup_for_class(
609 cl: ClassIR,
610 defaults_fn: FuncIR | None,
611 vtable_name: str,
612 shadow_vtable_name: str | None,
613 emitter: Emitter,
614) -> None:
615 """Generate a native function that allocates an instance of a class."""
616 emitter.emit_line(native_function_header(cl.setup, emitter))
617 emitter.emit_line("{")
618 type_arg_name = REG_PREFIX + cl.setup.sig.args[0].name
619 emitter.emit_line(f"PyTypeObject *type = (PyTypeObject*){type_arg_name};")
620 struct_name = cl.struct_name(emitter.names)
621 emitter.emit_line(f"{struct_name} *self;")
622
623 prefix = cl.name_prefix(emitter.names)
624 if cl.reuse_freed_instance:
625 # Attempt to use a per-type free list first (a free "list" with up to one object only).
626 emitter.emit_line(f"if ({prefix}_free_instance != NULL) {{")
627 emitter.emit_line(f"self = {prefix}_free_instance;")
628 emitter.emit_line(f"{prefix}_free_instance = NULL;")
629 emitter.emit_line("Py_SET_REFCNT(self, 1);")
630 if not cl.is_acyclic:
631 emitter.emit_line("PyObject_GC_Track(self);")
632 if defaults_fn is not None:
633 emit_attr_defaults_func_call(defaults_fn, "self", emitter)
634 emitter.emit_line("return (PyObject *)self;")
635 emitter.emit_line("}")
636
637 emitter.emit_line(f"self = ({cl.struct_name(emitter.names)} *)type->tp_alloc(type, 0);")
638 emitter.emit_line("if (self == NULL)")
639 emitter.emit_line(" return NULL;")
640
641 if shadow_vtable_name:
642 emitter.emit_line(f"if (type != {emitter.type_struct_name(cl)}) {{")
643 emitter.emit_line(f"self->vtable = {shadow_vtable_name};")
644 emitter.emit_line("} else {")
645 emitter.emit_line(f"self->vtable = {vtable_name};")
646 emitter.emit_line("}")
647 else:
648 emitter.emit_line(f"self->vtable = {vtable_name};")
649
650 emit_clear_bitmaps(cl, emitter)
651
652 if cl.has_method("__call__"):
653 name = cl.method_decl("__call__").cname(emitter.names)
654 emitter.emit_line(f"self->vectorcall = {PREFIX}{name};")
655
656 for base in reversed(cl.base_mro):
657 for attr, rtype in base.attributes.items():
658 value = emitter.c_undefined_value(rtype)
659
660 # We don't need to set this field to NULL since tp_alloc() already
661 # zero-initializes `self`.
662 if value != "NULL":
663 emitter.set_undefined_value(f"self->{emitter.attr(attr)}", rtype)
664
665 # Initialize attributes to default values, if necessary

Callers 1

generate_classFunction · 0.85

Calls 15

native_function_headerFunction · 0.90
emit_clear_bitmapsFunction · 0.85
reversedFunction · 0.85
name_prefixMethod · 0.80
type_struct_nameMethod · 0.80
has_methodMethod · 0.80
method_declMethod · 0.80
set_undefined_valueMethod · 0.80
attrMethod · 0.80
emit_lineMethod · 0.45
struct_nameMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…