Beispiel #1
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)
        params: List[Parameter] = []
        params = params + default_flags
        resolved_hints = get_type_hints(cls.__init__)
        sig = inspect.signature(cls.__init__)

        for name, p in sig.parameters.items():
            # Skip self as an attribute
            if name in ("self", "args", "kwargs"):
                continue
            type_ = type_cached = resolved_hints.get(name, p.annotation)
            default_ = p.default

            missing_value = default_ == sig.empty
            incompatible_value_type = not missing_value and is_incompatible(
                type(default_))
            missing_annotation_type = name not in resolved_hints
            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_value_type:
                missing_default = True

            collect_imports(imports, type_)

            if missing_default:
                default_ = "MISSING"
                string_imports.add("from omegaconf import MISSING")

            if incompatible_annotation_type:
                default_ = f"{default_}  # {type_str(type_cached)}"
            elif incompatible_value_type:
                default_ = f"{default_}  # {type_str(type(p.default))}"

            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,
    )
Beispiel #2
0
def generate_module(cfg: ConfigenConf, module: ModuleConf) -> str:
    classes_map: Dict[str, ClassInfo] = {}
    imports = set()
    string_imports: Set[str] = set()
    for class_name in module.classes:
        full_name = f"{module.name}.{class_name}"
        cls = hydra.utils.get_class(full_name)
        sig = inspect.signature(cls)
        params: List[Parameter] = []

        for name, p in sig.parameters.items():
            type_ = p.annotation
            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:
                    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(p.annotation)}"
                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,
    )
Beispiel #3
0
def generate_module(cfg: ConfigenConf, module: ModuleConf) -> str:
    classes_map: Dict[str, ClassInfo] = {}
    imports = set()
    string_imports: Set[str] = set()
    # Iterate through the classes in a given module.
    for class_name in module.classes:
        full_name = f"{module.name}.{class_name}"
        # Get class and init method sygnature.
        cls = hydra.utils.get_class(full_name)
        sig = inspect.signature(cls)

        # Iterate throught init arguments.
        params: List[Parameter] = []
        for name, p in sig.parameters.items():
            type_ = p.annotation
            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(p.annotation)}"
                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_,
                ))
        # Process module URL.
        if module.url is not None:
            url = (
                "\"\"\"For more details on parameteres please refer to the original documentation:\n"
                "    {}\n    \"\"\"".format(module.url))
        else:
            url = "None"
        classes_map[class_name] = ClassInfo(
            url=url,
            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,
    )