diff --git a/nevergrad/common/decorators.py b/nevergrad/common/decorators.py index b263a26b0..d102e2f36 100644 --- a/nevergrad/common/decorators.py +++ b/nevergrad/common/decorators.py @@ -33,8 +33,8 @@ def register_name( self, name: str, obj: X, info: tp.Optional[tp.Dict[tp.Hashable, tp.Any]] = None ) -> None: """Register an object with a provided name""" - # if name in self: - # raise RuntimeError(f'Encountered a name collision "{name}"') + if name in self: + raise RuntimeError(f'Encountered a name collision "{name}"') self[name] = obj if info is not None: assert isinstance(info, dict) diff --git a/nevergrad/parametrization/core.py b/nevergrad/parametrization/core.py index f2e52ae5c..edeeac2c5 100644 --- a/nevergrad/parametrization/core.py +++ b/nevergrad/parametrization/core.py @@ -42,7 +42,7 @@ class Parameter: value: ValueProperty[tp.Any] = ValueProperty() - def __init__(self, **parameters: tp.Any) -> None: + def __init__(self) -> None: # Main features self.uid = uuid.uuid4().hex self._treecall = utils.Treecall(self, Parameter) @@ -50,7 +50,6 @@ def __init__(self, **parameters: tp.Any) -> None: self.heritage: tp.Dict[tp.Hashable, tp.Any] = {"lineage": self.uid} # passed through to children self.loss: tp.Optional[float] = None # associated loss self._losses: tp.Optional[np.ndarray] = None # associated losses (multiobjective) as an array - self._parameters = None if not parameters else Dict(**parameters) # internal/model parameters self._dimension: tp.Optional[int] = None # Additional convenient features self._random_state: tp.Optional[np.random.RandomState] = None # lazy initialization @@ -100,15 +99,6 @@ def kwargs(self) -> tp.Dict[str, tp.Any]: """ return {} - @property - def parameters(self) -> "Dict": - """Internal/model parameters for this parameter""" - if self._parameters is None: # delayed instantiation to avoid infinte loop - assert self.__class__ != Dict, "parameters of Parameters dict should never be called" - self._parameters = Dict() - assert self._parameters is not None - return self._parameters - @property def dimension(self) -> int: """Dimension of the standardized space for this parameter @@ -242,7 +232,7 @@ def get_value_hash(self) -> tp.Hashable: if isinstance(val, (str, bytes, float, int)): return val elif isinstance(val, np.ndarray): - return val.tobytes() + return val.tobytes() # type: ignore else: raise utils.NotSupportedError(f"Value hash is not supported for object {self.name}") @@ -262,8 +252,8 @@ def name(self) -> str: if self._name is not None: return self._name substr = "" - if self._parameters is not None and self.parameters: - substr = f"[{self.parameters._get_parameters_str()}]" + if hasattr(self, "parameters"): # TODO temporary hack + substr = f"[{self.parameters._get_parameters_str()}]" # type: ignore if substr == "[]": substr = "" return f"{self._get_name()}" + substr @@ -396,10 +386,10 @@ def _check_frozen(self) -> None: def _internal_spawn_child(self: P) -> P: # default implem just forwards params - inputs = { - k: v.spawn_child() if isinstance(v, Parameter) else v for k, v in self.parameters._content.items() - } - child = self.__class__(**inputs) + # inputs = { + # k: v.spawn_child() if isinstance(v, Parameter) else v for k, v in self.parameters._content.items() + # } + child = self.__class__() # **inputs) return child def copy(self: P) -> P: # TODO test (see former instrumentation_copy test) diff --git a/nevergrad/parametrization/data.py b/nevergrad/parametrization/data.py index f67edd713..296990b6a 100644 --- a/nevergrad/parametrization/data.py +++ b/nevergrad/parametrization/data.py @@ -33,6 +33,10 @@ class Mutation(core.Parameter): # pylint: disable=unused-argument value: core.ValueProperty[tp.Callable[[tp.Sequence[D]], None]] = core.ValueProperty() + def __init__(self, **kwargs: tp.Any) -> None: + super().__init__() + self.parameters = core.Dict(**kwargs) + def _get_value(self) -> tp.Callable[[tp.Sequence[D]], None]: return self.apply @@ -80,7 +84,8 @@ def __init__( mutable_sigma: bool = False, ) -> None: sigma = Log(init=1.0, exponent=2.0, mutable_sigma=False) if mutable_sigma else 1.0 - super().__init__(sigma=sigma, recombination="average", mutation="gaussian") + super().__init__() + self.parameters = core.Dict(sigma=sigma, recombination="average", mutation="gaussian") err_msg = 'Exactly one of "init" or "shape" must be provided' self.parameters._ignore_in_repr = dict(sigma="1.0", recombination="average", mutation="gaussian") if init is not None: @@ -232,8 +237,7 @@ def set_bounds( return self def set_recombination(self: D, recombination: tp.Union[None, str, core.Parameter]) -> D: - assert self._parameters is not None - self._parameters._content["recombination"] = ( + self.parameters._content["recombination"] = ( recombination if isinstance(recombination, core.Parameter) else core.Constant(recombination) ) return self diff --git a/nevergrad/parametrization/helpers.py b/nevergrad/parametrization/helpers.py index dd184b3b7..16df4680d 100644 --- a/nevergrad/parametrization/helpers.py +++ b/nevergrad/parametrization/helpers.py @@ -55,8 +55,8 @@ def flatten_parameter( for x, y in content.items() } ) - if order > 0 and parameter._parameters is not None: - subparams = flatten_parameter(parameter.parameters, with_containers=False, order=order - 1) + if order > 0 and hasattr(parameter, "parameters"): + subparams = flatten_parameter(parameter.parameters, with_containers=False, order=order - 1) # type: ignore flat.update({"#" + str(x): y for x, y in subparams.items()}) if not with_containers: flat = {