def _compare(self, instance1, instance2, shortcut, rtol, atol, output): """Compare two config instances for equality with respect to this field. `lsst.pex.config.config.compare` is the primary user of this method. Parameters ---------- instance1 : `lsst.pex.config.Config` Left-hand-side `~lsst.pex.config.Config` instance in the comparison. instance2 : `lsst.pex.config.Config` Right-hand-side `~lsst.pex.config.Config` instance in the comparison. shortcut : `bool` If `True`, return as soon as an **inequality** is found. rtol : `float` Relative tolerance for floating point comparisons. atol : `float` Absolute tolerance for floating point comparisons. output : callable If not None, a callable that takes a `str`, used (possibly repeatedly) to report inequalities. Returns ------- equal : `bool` `True` if the fields are equal; `False` otherwise. Notes ----- Floating point comparisons are performed by `numpy.allclose`. """ l1 = getattr(instance1, self.name) l2 = getattr(instance2, self.name) name = getComparisonName(_joinNamePath(instance1._name, self.name), _joinNamePath(instance2._name, self.name)) if not compareScalars( "isnone for %s" % name, l1 is None, l2 is None, output=output): return False if l1 is None and l2 is None: return True if not compareScalars( "size for %s" % name, len(l1), len(l2), output=output): return False equal = True for n, v1, v2 in zip(range(len(l1)), l1, l2): result = compareScalars("%s[%d]" % (name, n), v1, v2, dtype=self.dtype, rtol=rtol, atol=atol, output=output) if not result and shortcut: return False equal = equal and result return equal
def __setitem__(self, k, value, at=None, label="assignment"): if self._config._frozen: raise FieldValidationError(self._field, self._config, "Cannot modify a frozen Config") try: dtype = self.types[k] except Exception: raise FieldValidationError(self._field, self._config, "Unknown key %r" % k) if value != dtype and type(value) != dtype: msg = "Value %s at key %s is of incorrect type %s. Expected type %s" % \ (value, k, _typeStr(value), _typeStr(dtype)) raise FieldValidationError(self._field, self._config, msg) if at is None: at = getCallStack() name = _joinNamePath(self._config._name, self._field.name, k) oldValue = self._dict.get(k, None) if oldValue is None: if value == dtype: self._dict[k] = value(__name=name, __at=at, __label=label) else: self._dict[k] = dtype(__name=name, __at=at, __label=label, **value._storage) else: if value == dtype: value = value() oldValue.update(__at=at, __label=label, **value._storage)
def save(self, outfile, instance): instanceDict = self.__get__(instance) fullname = _joinNamePath(instance._name, self.name) for v in instanceDict.values(): v._save(outfile) if self.multi: outfile.write(u"{}.names={!r}\n".format(fullname, instanceDict.names)) else: outfile.write(u"{}.name={!r}\n".format(fullname, instanceDict.name))
def _compare(self, instance1, instance2, shortcut, rtol, atol, output): """Compare two fields for equality. Used by `lsst.pex.ConfigDictField.compare`. 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. For example: `print`. Returns ------- isEqual : bool `True` if the fields are equal, `False` otherwise. Notes ----- Floating point comparisons are performed by `numpy.allclose`. """ c1 = getattr(instance1, self.name)._value c2 = getattr(instance2, self.name)._value name = getComparisonName(_joinNamePath(instance1._name, self.name), _joinNamePath(instance2._name, self.name)) return compareConfigs(name, c1, c2, shortcut=shortcut, rtol=rtol, atol=atol, output=output)
def save(self, outfile, instance): fullname = _joinNamePath(instance._name, self.name) value = self.__getOrMake(instance) target = value.target if target != self.target: # not targeting the field-default target. # save target information ConfigClass = value.ConfigClass outfile.write(u"{}.retarget(target={}, ConfigClass={})\n\n".format( fullname, _typeStr(target), _typeStr(ConfigClass))) # save field values value._save(outfile)
def __getitem__(self, k, at=None, label="default"): try: value = self._dict[k] except KeyError: try: dtype = self.types[k] except Exception: raise FieldValidationError( self._field, self._config, "Unknown key %r in Registry/ConfigChoiceField" % k) name = _joinNamePath(self._config._name, self._field.name, k) if at is None: at = getCallStack() at.insert(0, dtype._source) value = self._dict.setdefault( k, dtype(__name=name, __at=at, __label=label)) return value
def __initValue(self, at, label): """Construct value of field. Notes ----- If field.default is an instance of `lsst.pex.config.ConfigClass`, custom construct ``_value`` with the correct values from default. Otherwise, call ``ConfigClass`` constructor """ name = _joinNamePath(self._config._name, self._field.name) if type(self._field.default) == self.ConfigClass: storage = self._field.default._storage else: storage = {} value = self._ConfigClass(__name=name, __at=at, __label=label, **storage) object.__setattr__(self, "_value", value)
def rename(self, instance): fullname = _joinNamePath(instance._name, self.name) value = self.__getOrMake(instance) value._rename(fullname)
def _compare(self, instance1, instance2, shortcut, rtol, atol, output): """Compare two fields for equality. Used by `lsst.pex.ConfigChoiceField.compare`. 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 ----- Only the selected configurations are compared, as the parameters of any others do not matter. Floating point comparisons are performed by `numpy.allclose`. """ d1 = getattr(instance1, self.name) d2 = getattr(instance2, self.name) name = getComparisonName(_joinNamePath(instance1._name, self.name), _joinNamePath(instance2._name, self.name)) if not compareScalars("selection for %s" % name, d1._selection, d2._selection, output=output): return False if d1._selection is None: return True if self.multi: nested = [(k, d1[k], d2[k]) for k in d1._selection] else: nested = [(d1._selection, d1[d1._selection], d2[d1._selection])] equal = True for k, c1, c2 in nested: result = compareConfigs("%s[%r]" % (name, k), c1, c2, shortcut=shortcut, rtol=rtol, atol=atol, output=output) if not result and shortcut: return False equal = equal and result return equal
def rename(self, instance): instanceDict = self.__get__(instance) fullname = _joinNamePath(instance._name, self.name) instanceDict._rename(fullname)
def _rename(self, fullname): for k, v in self._dict.items(): v._rename(_joinNamePath(name=fullname, index=k))