def generate_module()

in tools/configen/configen/configen.py [0:0]


def generate_module(cfg: ConfigenConf, module: ModuleConf) -> str:
    classes_map: Dict[str, ClassInfo] = {}
    imports = set()
    string_imports: Set[str] = set()

    default_flags = get_default_flags(module)

    for class_name in module.classes:
        full_name = f"{module.name}.{class_name}"
        cls = hydra.utils.get_class(full_name)
        sig = inspect.signature(cls)
        resolved_hints = get_type_hints(cls.__init__)
        params: List[Parameter] = []
        params = params + default_flags

        for name, p in sig.parameters.items():
            type_ = original_type = resolved_hints.get(name, sig.empty)
            default_ = p.default

            missing_value = default_ == sig.empty
            incompatible_value_type = not missing_value and is_incompatible(
                type(default_)
            )

            missing_annotation_type = type_ == sig.empty
            incompatible_annotation_type = (
                not missing_annotation_type and is_incompatible(type_)
            )

            if missing_annotation_type or incompatible_annotation_type:
                type_ = Any
                collect_imports(imports, Any)

            if not missing_value:
                if type_ == str or type(default_) == str:
                    default_ = f'"{default_}"'
                elif isinstance(default_, list):
                    default_ = f"field(default_factory=lambda: {default_})"
                elif isinstance(default_, dict):
                    default_ = f"field(default_factory=lambda: {default_})"

            missing_default = missing_value
            if (
                incompatible_annotation_type
                or incompatible_value_type
                or missing_default
            ):
                missing_default = True

            collect_imports(imports, type_)

            if missing_default:
                if incompatible_annotation_type:
                    default_ = f"MISSING  # {type_str(original_type)}"
                elif incompatible_value_type:
                    default_ = f"MISSING  # {type_str(type(p.default))}"
                else:
                    default_ = "MISSING"
                string_imports.add("from omegaconf import MISSING")

            params.append(
                Parameter(
                    name=name,
                    type_str=type_str(type_),
                    default=default_,
                )
            )
        classes_map[class_name] = ClassInfo(
            target=full_name,
            module=module.name,
            name=class_name,
            parameters=params,
        )

    template = jinja_env.get_template("module.j2")
    return template.render(
        imports=convert_imports(imports, string_imports),
        classes=module.classes,
        classes_map=classes_map,
        header=cfg.header,
    )