def _get_kwargs(config: Union[ObjectConf, DictConfig], **kwargs: Any) -> Any: # copy config to avoid mutating it when merging with kwargs config_copy = copy.deepcopy(config) # Manually set parent as deepcopy does not currently handles it (https://github.com/omry/omegaconf/issues/130) # noinspection PyProtectedMember config_copy._set_parent(config._get_parent()) # type: ignore config = config_copy params = config.params if "params" in config else OmegaConf.create() assert isinstance( params, DictConfig ), f"Input config params are expected to be a mapping, found {type(config.params).__name__}" primitives = {} rest = {} for k, v in kwargs.items(): if _utils.is_primitive_type(v) or isinstance(v, (dict, list)): primitives[k] = v else: rest[k] = v final_kwargs = {} with read_write(params): params.merge_with(OmegaConf.create(primitives)) for k, v in params.items(): final_kwargs[k] = v for k, v in rest.items(): final_kwargs[k] = v return final_kwargs
def _instantiate_class(clazz: Type[Any], config: PluginConf, *args: Any, **kwargs: Any) -> Any: import copy # copy config to avoid mutating it when merging with kwargs config_copy = copy.deepcopy(config) # Manually set parent as deepcopy does not currently handles it (https://github.com/omry/omegaconf/issues/130) # noinspection PyProtectedMember config_copy._set_parent(config._get_parent()) # type: ignore config = config_copy params = config.params if "params" in config else OmegaConf.create() assert isinstance( params, DictConfig ), "Input config params are expected to be a mapping, found {}".format( type(config.params)) primitives = {} rest = {} for k, v in kwargs.items(): if _utils._is_primitive_type(v) or isinstance(v, (dict, list)): primitives[k] = v else: rest[k] = v final_kwargs = {} params.merge_with(OmegaConf.create(primitives)) for k, v in params.items(): final_kwargs[k] = v for k, v in rest.items(): final_kwargs[k] = v return clazz(*args, **final_kwargs)
def _get_kwargs(config: Union[ObjectConf, DictConfig], **kwargs: Any) -> Any: # copy config to avoid mutating it when merging with kwargs config_copy = copy.deepcopy(config) # Manually set parent as deepcopy does not currently handles it (https://github.com/omry/omegaconf/issues/130) # noinspection PyProtectedMember config_copy._set_parent(config._get_parent()) # type: ignore config = config_copy params = config.params if "params" in config else OmegaConf.create() assert isinstance( params, DictConfig ), f"Input config params are expected to be a mapping, found {type(config.params).__name__}" return {**dict(params), **kwargs}
def call(config: Any, *args: Any, **kwargs: Any) -> Any: """ :param config: An object describing what to call and what params to use. Must have a _target_ field. :param args: optional positional parameters pass-through :param kwargs: optional named parameters pass-through :return: the return value from the specified class or method """ if OmegaConf.is_none(config): return None if isinstance(config, TargetConf) and config._target_ == "???": # Specific check to give a good warning about failure to annotate _target_ as a string. raise InstantiationException( f"Missing value for {type(config).__name__}._target_. Check that it's properly annotated and overridden." f"\nA common problem is forgetting to annotate _target_ as a string : '_target_: str = ...'" ) if not (isinstance(config, dict) or OmegaConf.is_config(config) or is_structured_config(config)): raise HydraException( f"Unsupported config type : {type(config).__name__}") # make a copy to ensure we do not change the provided object config_copy = OmegaConf.structured(config) if OmegaConf.is_config(config): config_copy._set_parent(config._get_parent()) config = config_copy cls = "<unknown>" try: assert isinstance(config, DictConfig) OmegaConf.set_readonly(config, False) OmegaConf.set_struct(config, False) cls = _get_cls_name(config) type_or_callable = _locate(cls) if isinstance(type_or_callable, type): return _instantiate_class(type_or_callable, config, *args, **kwargs) else: assert callable(type_or_callable) return _call_callable(type_or_callable, config, *args, **kwargs) except InstantiationException as e: raise e except Exception as e: raise HydraException(f"Error calling '{cls}' : {e}") from e
def instantiate(config: DictConfig, *args: Any, **kwargs: Any) -> Any: import copy assert config is not None, "Input config is None" # copy config to avoid mutating it when merging with kwargs config_copy = copy.deepcopy(config) config_copy._set_parent(config._get_parent()) config = config_copy try: clazz = get_class(config["class"]) params = config.params if "params" in config else OmegaConf.create() assert isinstance( params, DictConfig ), "Input config params are expected to be a mapping, found {}".format( type(config.params)) params.merge_with(OmegaConf.create(kwargs)) return clazz(*args, **params) except Exception as e: log.error("Error instantiating {} : {}".format(config["class"], e)) raise e
def _get_kwargs( config: Union[DictConfig, ListConfig], root: bool = True, **kwargs: Any, ) -> Any: from hydra.utils import instantiate assert OmegaConf.is_config(config) if OmegaConf.is_list(config): assert isinstance(config, ListConfig) return [ _get_kwargs(x, root=False) if OmegaConf.is_config(x) else x for x in config ] assert OmegaConf.is_dict( config), "Input config is not an OmegaConf DictConfig" recursive = _is_recursive(config, kwargs) overrides = OmegaConf.create(kwargs, flags={"allow_objects": True}) config.merge_with(overrides) final_kwargs = OmegaConf.create(flags={"allow_objects": True}) final_kwargs._set_parent(config._get_parent()) final_kwargs._set_flag("readonly", False) final_kwargs._set_flag("struct", False) if recursive: for k, v in config.items_ex(resolve=False): if OmegaConf.is_none(v): final_kwargs[k] = v elif _is_target(v): final_kwargs[k] = instantiate(v) elif OmegaConf.is_dict(v): d = OmegaConf.create({}, flags={"allow_objects": True}) for key, value in v.items_ex(resolve=False): if _is_target(value): d[key] = instantiate(value) elif OmegaConf.is_config(value): d[key] = _get_kwargs(value, root=False) else: d[key] = value d._metadata.object_type = v._metadata.object_type final_kwargs[k] = d elif OmegaConf.is_list(v): lst = OmegaConf.create([], flags={"allow_objects": True}) for x in v: if _is_target(x): lst.append(instantiate(x)) elif OmegaConf.is_config(x): lst.append(_get_kwargs(x, root=False)) lst[-1]._metadata.object_type = x._metadata.object_type else: lst.append(x) final_kwargs[k] = lst else: final_kwargs[k] = v else: for k, v in config.items_ex(resolve=False): final_kwargs[k] = v final_kwargs._set_flag("readonly", None) final_kwargs._set_flag("struct", None) final_kwargs._set_flag("allow_objects", None) if not root: # This is tricky, since the root kwargs is exploded anyway we can treat is as an untyped dict # the motivation is that the object type is used as an indicator to treat the object differently during # conversion to a primitive container in some cases final_kwargs._metadata.object_type = config._metadata.object_type return final_kwargs
def instantiate(config: Any, *args: Any, **kwargs: Any) -> Any: """ :param config: An config object describing what to call and what params to use. In addition to the parameters, the config must contain: _target_ : target class or callable name (str) And may contain: _recursive_: Construct nested objects as well (bool). True by default. may be overridden via a _recursive_ key in the kwargs _convert_: Conversion strategy none : Passed objects are DictConfig and ListConfig, default partial : Passed objects are converted to dict and list, with the exception of Structured Configs (and their fields). all : Passed objects are dicts, lists and primitives without a trace of OmegaConf containers :param args: Optional positional parameters pass-through :param kwargs: Optional named parameters to override parameters in the config object. Parameters not present in the config objects are being passed as is to the target. :return: if _target_ is a class name: the instantiated object if _target_ is a callable: the return value of the call """ if OmegaConf.is_none(config): return None if isinstance(config, TargetConf) and config._target_ == "???": # Specific check to give a good warning about failure to annotate _target_ as a string. raise InstantiationException( f"Missing value for {type(config).__name__}._target_. Check that it's properly annotated and overridden." f"\nA common problem is forgetting to annotate _target_ as a string : '_target_: str = ...'" ) if not ( isinstance(config, dict) or OmegaConf.is_config(config) or is_structured_config(config) ): raise HydraException(f"Unsupported config type : {type(config).__name__}") if isinstance(config, dict): configc = config.copy() _convert_container_targets_to_strings(configc) config = configc kwargsc = kwargs.copy() _convert_container_targets_to_strings(kwargsc) kwargs = kwargsc # make a copy to ensure we do not change the provided object config_copy = OmegaConf.structured(config, flags={"allow_objects": True}) if OmegaConf.is_config(config): config_copy._set_parent(config._get_parent()) config = config_copy assert OmegaConf.is_config(config) OmegaConf.set_readonly(config, False) OmegaConf.set_struct(config, False) target = _get_target_type(config, kwargs) try: config._set_flag("allow_objects", True) final_kwargs = _get_kwargs(config, **kwargs) convert = _pop_convert_mode(final_kwargs) if convert == ConvertMode.PARTIAL: final_kwargs = OmegaConf.to_container( final_kwargs, resolve=True, exclude_structured_configs=True ) return target(*args, **final_kwargs) elif convert == ConvertMode.ALL: final_kwargs = OmegaConf.to_container(final_kwargs, resolve=True) return target(*args, **final_kwargs) elif convert == ConvertMode.NONE: return target(*args, **final_kwargs) else: assert False except Exception as e: # preserve the original exception backtrace raise type(e)( f"Error instantiating/calling '{_convert_target_to_string(target)}' : {e}" ).with_traceback(sys.exc_info()[2])
def instantiate(config: Any, *args: Any, **kwargs: Any) -> Any: """ :param config: An config object describing what to call and what params to use. In addition to the parameters, the config must contain: _target_ : target class or callable name (str) _recursive_: Construct nested objects as well (bool). True by default. may be overridden via a _recursive_ key in the kwargs :param args: Optional positional parameters pass-through :param kwargs: Optional named parameters to override parameters in the config object. Parameters not present in the config objects are being passed as is to the target. :return: if _target_ is a class name: the instantiated object if _target_ is a callable: the return value of the call """ if OmegaConf.is_none(config): return None if isinstance(config, TargetConf) and config._target_ == "???": # Specific check to give a good warning about failure to annotate _target_ as a string. raise InstantiationException( f"Missing value for {type(config).__name__}._target_. Check that it's properly annotated and overridden." f"\nA common problem is forgetting to annotate _target_ as a string : '_target_: str = ...'" ) if not ( isinstance(config, dict) or OmegaConf.is_config(config) or is_structured_config(config) ): raise HydraException(f"Unsupported config type : {type(config).__name__}") if isinstance(config, dict): configc = config.copy() _convert_container_targets_to_strings(configc) config = configc kwargsc = kwargs.copy() _convert_container_targets_to_strings(kwargsc) kwargs = kwargsc # make a copy to ensure we do not change the provided object config_copy = OmegaConf.structured(config, flags={"allow_objects": True}) if OmegaConf.is_config(config): config_copy._set_parent(config._get_parent()) config = config_copy assert OmegaConf.is_config(config) OmegaConf.set_readonly(config, False) OmegaConf.set_struct(config, False) target = _get_target_type(config, kwargs) try: config._set_flag("allow_objects", True) final_kwargs = _get_kwargs(config, **kwargs) return target(*args, **final_kwargs) except Exception as e: raise type(e)( f"Error instantiating/calling '{_convert_target_to_string(target)}' : {e}" )