def rename(self, instance: Config): actionStruct: ConfigurableActionStruct = self.__get__(instance) if actionStruct is not None: for k, v in actionStruct.items(): base_name = _joinNamePath(instance._name, self.name) fullname = _joinNamePath(base_name, k) v._rename(fullname)
def __setattr__(self, attr: str, value: Union[ActionTypeVar, Type[ActionTypeVar]], at=None, label='setattr', setHistory=False) -> None: if hasattr(self._config, '_frozen') and self._config._frozen: msg = "Cannot modify a frozen Config. "\ f"Attempting to set item {attr} to value {value}" raise FieldValidationError(self._field, self._config, msg) # verify that someone has not passed a string with a space or leading # number or something through the dict assignment update interface if not attr.isidentifier(): raise ValueError( "Names used in ConfigurableStructs must be valid as python variable names" ) if attr not in (self.__dict__.keys() | type(self).__dict__.keys()): base_name = _joinNamePath(self._config._name, self._field.name) name = _joinNamePath(base_name, attr) if at is None: at = getCallStack() if isinstance(value, ConfigurableAction): valueInst = type(value)(__name=name, __at=at, __label=label, **value._storage) else: valueInst = value(__name=name, __at=at, __label=label) self._attrs[attr] = valueInst else: super().__setattr__(attr, value)
def _compare(self, instance1, instance2, shortcut, rtol, atol, output): """Compare two fields for equality. Parameters ---------- instance1 : `lsst.pex.config.Config` Left-hand side config instance to compare. instance2 : `lsst.pex.config.Config` Right-hand side config instance to compare. shortcut : `bool` If `True`, this function returns as soon as an inequality if found. rtol : `float` Relative tolerance for floating point comparisons. atol : `float` Absolute tolerance for floating point comparisons. output : callable A callable that takes a string, used (possibly repeatedly) to report inequalities. Returns ------- isEqual : bool `True` if the fields are equal, `False` otherwise. Notes ----- Floating point comparisons are performed by `numpy.allclose`. """ d1: ConfigurableActionStruct = getattr(instance1, self.name) d2: ConfigurableActionStruct = getattr(instance2, self.name) name = getComparisonName(_joinNamePath(instance1._name, self.name), _joinNamePath(instance2._name, self.name)) if not compareScalars(f"keys for {name}", set(d1.fieldNames), set(d2.fieldNames), output=output): return False equal = True for k, v1 in d1.items(): v2 = getattr(d2, k) result = compareConfigs(f"{name}.{k}", v1, v2, shortcut=shortcut, rtol=rtol, atol=atol, output=output) if not result and shortcut: return False equal = equal and result return equal
def __set__( self, instance: Config, value: ActionTypeVar | type[ActionTypeVar], at: Any = None, label: str = "assignment" ) -> None: if instance._frozen: raise FieldValidationError(self, instance, "Cannot modify a frozen Config") name = _joinNamePath(prefix=instance._name, name=self.name) if not isinstance(value, self.dtype) and not issubclass(value, self.dtype): msg = f"Value {value} is of incorrect type {_typeStr(value)}. Expected {_typeStr(self.dtype)}" raise FieldValidationError(self, instance, msg) if at is None: at = getCallStack() if isinstance(value, self.dtype): instance._storage[self.name] = type(value)(__name=name, __at=at, __label=label, **value._storage) else: instance._storage[self.name] = value(__name=name, __at=at, __label=label) history = instance._history.setdefault(self.name, []) history.append(("config value set", at, label))
def save(self, outfile, instance): # docstring inherited from parent # This is different that the parent class in that this field must # serialize which config class is assigned to this field prior to # serializing any assignments to that config class's fields. value = self.__get__(instance) fullname = _joinNamePath(instance._name, self.name) outfile.write(f"{fullname}={_typeStr(value)}\n") super().save(outfile, instance)
def save(self, outfile, instance): actionStruct = self.__get__(instance) fullname = _joinNamePath(instance._name, self.name) # Ensure that a struct is always empty before assigning to it. outfile.write(f"{fullname}=None\n") if actionStruct is None: return for v in actionStruct: outfile.write(u"{}={}()\n".format(v._name, _typeStr(v))) v._save(outfile)