Repository: microsoft/nni
File: nni/utils.py (Python)

Code before:
    namespace or dict
        The updated ``base_params``. Note that ``base_params`` will be updated inplace. The return value is
        only for convenience.
    """
    if override_params is None:
        return base_params
    is_dict = isinstance(base_params, dict)
    for k, v in override_params.items():
        if is_dict:
            if k not in base_params:
                raise ValueError('Key \'%s\' not found in base parameters.' % k)
            if type(base_params[k]) != type(v) and base_params[k] is not None:
                raise TypeError('Expected \'%s\' in override parameters to have type \'%s\', but found \'%s\'.' %
                                (k, type(base_params[k]), type(v)))
            base_params[k] = v
        else:
            if not hasattr(base_params, k):
                raise ValueError('Key \'%s\' not found in base parameters.' % k)
            if type(getattr(base_params, k)) != type(v) and getattr(base_params, k) is not None:
                raise TypeError('Expected \'%s\' in override parameters to have type \'%s\', but found \'%s\'.' %
                                (k, type(getattr(base_params, k)), type(v)))
            setattr(base_params, k, v)
    return base_params

class ClassArgsValidator(object):
    """
    NNI tuners/assessors/adivisors accept a `classArgs` parameter in experiment configuration file.
    This ClassArgsValidator interface is used to validate the classArgs section in exeperiment
    configuration file.
    """
    def validate_class_args(self, **kwargs):
        """
        Validate the classArgs configuration in experiment configuration file.

        Parameters
        ----------
        kwargs: dict
            kwargs passed to tuner/assessor/advisor constructor

        Raises:
            Raise an execption if the kwargs is invalid.
        """
        pass

    def choices(self, key, *args):
        """
        Utility method to create a scheme to check whether the `key` is one of the `args`.

        Parameters:
        ----------
        key: str

Review comment (suggestion):
I tried to google "implicit cast rules for Python", but found rarely anything helpful. I guess this should work.

Code after:
    namespace or dict
        The updated ``base_params``. Note that ``base_params`` will be updated inplace. The return value is
        only for convenience.
    """
    if override_params is None:
        return base_params
    is_dict = isinstance(base_params, dict)
    for k, v in override_params.items():
        if is_dict:
            if k not in base_params:
                raise ValueError('Key \'%s\' not found in base parameters.' % k)
            v = _ensure_compatible_type(k, base_params[k], v)
            base_params[k] = v
        else:
            if not hasattr(base_params, k):
                raise ValueError('Key \'%s\' not found in base parameters.' % k)
            v = _ensure_compatible_type(k, getattr(base_params, k), v)
            setattr(base_params, k, v)
    return base_params

def _ensure_compatible_type(key, base, override):
    if base is None:
        return override
    if isinstance(override, type(base)):
        return override
    if isinstance(base, float) and isinstance(override, int):
        return float(override)
    base_type = type(base).__name__
    override_type = type(override).__name__
    raise ValueError(f'Expected "{key}" in override parameters to have type {base_type}, but found {override_type}')

class ClassArgsValidator(object):
    """
    NNI tuners/assessors/adivisors accept a `classArgs` parameter in experiment configuration file.
    This ClassArgsValidator interface is used to validate the classArgs section in exeperiment
    configuration file.
    """
    def validate_class_args(self, **kwargs):
        """
        Validate the classArgs configuration in experiment configuration file.

        Parameters
        ----------
        kwargs: dict
            kwargs passed to tuner/assessor/advisor constructor

        Raises:
            Raise an execption if the kwargs is invalid.
        """
        pass