Example #1
0
def is_incompatible(type_: Type[Any]) -> bool:

    opt = _resolve_optional(type_)
    # Unions are not supported (Except Optional)
    if not opt[0] and _is_union(type_):
        return True

    type_ = opt[1]
    if type_ in (type(None), tuple, list, dict):
        return False

    try:
        if is_list_annotation(type_):
            lt = get_list_element_type(type_)
            return is_incompatible(lt)
        if is_dict_annotation(type_):
            kvt = get_dict_key_value_types(type_)
            if not issubclass(kvt[0], (str, Enum)):
                return True
            return is_incompatible(kvt[1])
        if is_tuple_annotation(type_):
            for arg in type_.__args__:
                if arg is not ... and is_incompatible(arg):
                    return True
            return False
        if get_origin(type_) is Callable:
            args = get_args(type_)
            for arg in args[0]:
                if arg is not ... and is_incompatible(arg):
                    return True
            if is_incompatible(args[1]):
                return True
            return False

    except ValidationError:
        return True

    if type_ is Any or issubclass(type_, (int, float, str, bool, Enum)):
        return False
    if is_structured_config(type_):
        try:
            OmegaConf.structured(type_)  # verify it's actually legal
        except ValidationError as e:
            log.debug(
                f"Failed to create DictConfig from ({type_.__name__}) : {e}, flagging as incompatible"
            )
            return True
        return False
    return True
Example #2
0
def generate(cfg: ConfigenConf, module_name: str, class_name: str) -> str:
    full_name = f"{module_name}.{class_name}"
    cls = hydra.utils.get_class(full_name)
    sig = inspect.signature(cls)
    template = jinja_env.get_template("dataclass.j2")
    params: List[Parameter] = []
    for name, p in sig.parameters.items():
        type_ = p.annotation
        if type_ == sig.empty or _is_union(type_):
            type_ = Any
        params.append(
            Parameter(
                name=name,
                type_str=type_str(type_),
                default=p.default,
                passthrough=_is_passthrough(type_),
            ))
    return template.render(target=f'"{full_name}"',
                           class_name=class_name,
                           params=params,
                           header=cfg.header)