Beispiel #1
0
    def instantiate(config: Union[DictConfig, dict], *args, **kwargs) -> Any:
        r"""
        Recursively instantiates classes in a Hydra configuration.

        Args:
            config (omegaconf.DictConfig or dict):
                The config to recursively instantiate from.

        """
        # NOTE this method is really ugly, but it's coming in Hydra 1.1 so no reason
        # to rewrite it
        if isinstance(config, dict):
            config = DictConfig(config)
        elif isinstance(config, list):
            config = ListConfig(config)  # type: ignore

        # deepcopy so we can modify config
        config = deepcopy(config)
        if isinstance(config, DictConfig):
            OmegaConf.set_struct(config, False)

        if "params" in config.keys():
            if isinstance(config.get("params"), (dict, DictConfig)):
                params = dict(config.get("params"))  # type: ignore
            elif isinstance(config.get("params"), (list, ListConfig)):
                params = list(config.get("params"))  # type: ignore
        else:
            params = {}

        def is_subclass(d):
            if isinstance(d, (dict, DictConfig)):
                return _has_instantiate_key(d.keys())
            elif isinstance(d, (list, ListConfig)):
                return any([_has_instantiate_key(x.keys()) for x in d if isinstance(x, (dict, DictConfig))])
            return False

        if isinstance(params, list):  # type: ignore
            for i, subconfig in enumerate(params):
                subconfig = DictConfig(subconfig)
                if isinstance(subconfig, (dict, DictConfig)) and "params" not in subconfig.keys():
                    subconfig["params"] = {}
                subconfig._set_parent(config)  # type: ignore
                params[i] = HydraMixin.instantiate(subconfig)
            del config["params"]
            return instantiate(config, *params, *args, **kwargs)

        else:
            subclasses = {key: subconfig for key, subconfig in params.items() if is_subclass(subconfig)}  # type: ignore

            # instantiate recursively, remove those keys from config used in hydra instantiate call
            for key, subconfig in subclasses.items():

                if isinstance(subconfig, (dict, DictConfig)):
                    subconfig = DictConfig(subconfig)
                    # avoid issues when cls given without params
                    if "params" not in subconfig:
                        subconfig["params"] = {}
                    subconfig._set_parent(config)  # type: ignore
                    subclasses[key] = HydraMixin.instantiate(subconfig)
                else:
                    subclasses[key] = [HydraMixin.instantiate(x) for x in subconfig]

                del config.get("params")[key]

            subclasses.update(kwargs)
            return instantiate(config, *args, **subclasses)