def validateItem(self, i, x): """Validate an item to determine if it can be included in the list. Parameters ---------- i : `int` Index of the item in the `list`. x : object Item in the `list`. Raises ------ FieldValidationError Raised if an item in the ``value`` parameter does not have the appropriate type for this field or does not pass the field's `ListField.itemCheck` method. """ if not isinstance(x, self._field.itemtype) and x is not None: msg = "Item at position %d with value %s is of incorrect type %s. Expected %s" % \ (i, x, _typeStr(x), _typeStr(self._field.itemtype)) raise FieldValidationError(self._field, self._config, msg) if self._field.itemCheck is not None and not self._field.itemCheck(x): msg = "Item at position %d is not a valid value: %s" % (i, x) raise FieldValidationError(self._field, self._config, msg)
def __init__(self, doc, target, ConfigClass=None, default=None, check=None, deprecated=None): ConfigClass = self.validateTarget(target, ConfigClass) if default is None: default = ConfigClass if default != ConfigClass and type(default) != ConfigClass: raise TypeError("'default' is of incorrect type %s. Expected %s" % (_typeStr(default), _typeStr(ConfigClass))) source = getStackFrame() self._setup(doc=doc, dtype=ConfigurableInstance, default=default, check=check, optional=False, source=source, deprecated=deprecated) self.target = target self.ConfigClass = ConfigClass
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): 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 __init__(self, dict_, value, at=None, label="assignment", setHistory=True): if at is None: at = getCallStack() self._dict = dict_ self._field = self._dict._field self._config = self._dict._config self.__history = self._config._history.setdefault(self._field.name, []) if value is not None: try: for v in value: if v not in self._dict: # invoke __getitem__ to ensure it's present self._dict.__getitem__(v, at=at) except TypeError: msg = "Value %s is of incorrect type %s. Sequence type expected" % ( value, _typeStr(value)) raise FieldValidationError(self._field, self._config, msg) self._set = set(value) else: self._set = set() if setHistory: self.__history.append(("Set selection to %s" % self, at, label))
def __init__(self, doc, dtype, default=None, optional=False, min=None, max=None, inclusiveMin=True, inclusiveMax=False, deprecated=None): if dtype not in self.supportedTypes: raise ValueError("Unsupported RangeField dtype %s" % (_typeStr(dtype))) source = getStackFrame() if min is None and max is None: raise ValueError("min and max cannot both be None") if min is not None and max is not None: if min > max: raise ValueError("min = %s > %s = max" % (min, max)) elif min == max and not (inclusiveMin and inclusiveMax): raise ValueError( "min = max = %s and min and max not both inclusive" % (min, )) self.min = min """Minimum value accepted in the range. If `None`, the range has no lower bound (equivalent to negative infinity). """ self.max = max """Maximum value accepted in the range. If `None`, the range has no upper bound (equivalent to positive infinity). """ if inclusiveMax: self.maxCheck = lambda x, y: True if y is None else x <= y else: self.maxCheck = lambda x, y: True if y is None else x < y if inclusiveMin: self.minCheck = lambda x, y: True if y is None else x >= y else: self.minCheck = lambda x, y: True if y is None else x > y self._setup(doc, dtype=dtype, default=default, check=None, optional=optional, source=source, deprecated=deprecated) self.rangeString = "%s%s,%s%s" % \ (("[" if inclusiveMin else "("), ("-inf" if self.min is None else self.min), ("inf" if self.max is None else self.max), ("]" if inclusiveMax else ")")) """String representation of the field's allowed range (`str`). """ self.__doc__ += "\n\nValid Range = " + self.rangeString
def __init__(self, doc, dtype, allowed, default=None, optional=True, deprecated=None): self.allowed = dict(allowed) if optional and None not in self.allowed: self.allowed[None] = "Field is optional" if len(self.allowed) == 0: raise ValueError("ChoiceFields must allow at least one choice") Field.__init__(self, doc=doc, dtype=dtype, default=default, check=None, optional=optional, deprecated=deprecated) self.__doc__ += "\n\nAllowed values:\n\n" for choice, choiceDoc in self.allowed.items(): if choice is not None and not isinstance(choice, dtype): raise ValueError("ChoiceField's allowed choice %s is of incorrect type %s. Expected %s" % (choice, _typeStr(choice), _typeStr(dtype))) self.__doc__ += "%s\n %s\n" % ('``{0!r}``'.format(str(choice)), choiceDoc) self.source = getStackFrame()
def __set__(self, instance, value, at=None, label="assignment"): if instance._frozen: raise FieldValidationError(self, instance, "Cannot modify a frozen Config") if at is None: at = getCallStack() oldValue = self.__getOrMake(instance, at=at) if isinstance(value, ConfigurableInstance): oldValue.retarget(value.target, value.ConfigClass, at, label) oldValue.update(__at=at, __label=label, **value._storage) elif type(value) == oldValue._ConfigClass: oldValue.update(__at=at, __label=label, **value._storage) elif value == oldValue.ConfigClass: value = oldValue.ConfigClass() oldValue.update(__at=at, __label=label, **value._storage) else: msg = "Value %s is of incorrect type %s. Expected %s" % \ (value, _typeStr(value), _typeStr(oldValue.ConfigClass)) raise FieldValidationError(self, instance, msg)
def __setattr__(self, attr, value, at=None, label="assignment"): if hasattr(getattr(self.__class__, attr, None), '__set__'): # This allows properties to work. object.__setattr__(self, attr, value) elif attr in self.__dict__ or attr in [ "_field", "_config", "_history", "_list", "__doc__" ]: # This allows specific private attributes to work. object.__setattr__(self, attr, value) else: # We throw everything else. msg = "%s has no attribute %s" % (_typeStr(self._field), attr) raise FieldValidationError(self._field, self._config, msg)
def retarget(self, target, ConfigClass=None, at=None, label="retarget"): """Target a new configurable and ConfigClass """ if self._config._frozen: raise FieldValidationError(self._field, self._config, "Cannot modify a frozen Config") try: ConfigClass = self._field.validateTarget(target, ConfigClass) except BaseException as e: raise FieldValidationError(self._field, self._config, str(e)) if at is None: at = getCallStack() object.__setattr__(self, "_target", target) if ConfigClass != self.ConfigClass: object.__setattr__(self, "_ConfigClass", ConfigClass) self.__initValue(at, label) history = self._config._history.setdefault(self._field.name, []) msg = "retarget(target=%s, ConfigClass=%s)" % (_typeStr(target), _typeStr(ConfigClass)) history.append((msg, at, label))
def __init__(self, config, field, value, at, label, setHistory=True): self._field = field self._config = config self._history = self._config._history.setdefault(self._field.name, []) self._list = [] self.__doc__ = field.doc if value is not None: try: for i, x in enumerate(value): self.insert(i, x, setHistory=False) except TypeError: msg = "Value %s is of incorrect type %s. Sequence type expected" % ( value, _typeStr(value)) raise FieldValidationError(self._field, self._config, msg) if setHistory: self.history.append((list(self._list), at, label))
def validateTarget(self, target, ConfigClass): """Validate the target and configuration class. Parameters ---------- target The configurable being verified. ConfigClass : `lsst.pex.config.Config`-type or `None` The configuration class associated with the ``target``. This can be `None` if ``target`` has a ``ConfigClass`` attribute. Raises ------ AttributeError Raised if ``ConfigClass`` is `None` and ``target`` does not have a ``ConfigClass`` attribute. TypeError Raised if ``ConfigClass`` is not a `~lsst.pex.config.Config` subclass. ValueError Raised if: - ``target`` is not callable (callables have a ``__call__`` method). - ``target`` is not startically defined (does not have ``__module__`` or ``__name__`` attributes). """ if ConfigClass is None: try: ConfigClass = target.ConfigClass except Exception: raise AttributeError( "'target' must define attribute 'ConfigClass'") if not issubclass(ConfigClass, Config): raise TypeError("'ConfigClass' is of incorrect type %s." "'ConfigClass' must be a subclass of Config" % _typeStr(ConfigClass)) if not hasattr(target, '__call__'): raise ValueError("'target' must be callable") if not hasattr(target, '__module__') or not hasattr( target, '__name__'): raise ValueError( "'target' must be statically defined" "(must have '__module__' and '__name__' attributes)") return ConfigClass
def __init__(self, doc, dtype, default=None, optional=False, listCheck=None, itemCheck=None, length=None, minLength=None, maxLength=None, deprecated=None): if dtype not in Field.supportedTypes: raise ValueError("Unsupported dtype %s" % _typeStr(dtype)) if length is not None: if length <= 0: raise ValueError("'length' (%d) must be positive" % length) minLength = None maxLength = None else: if maxLength is not None and maxLength <= 0: raise ValueError("'maxLength' (%d) must be positive" % maxLength) if minLength is not None and maxLength is not None \ and minLength > maxLength: raise ValueError("'maxLength' (%d) must be at least" " as large as 'minLength' (%d)" % (maxLength, minLength)) if listCheck is not None and not hasattr(listCheck, "__call__"): raise ValueError("'listCheck' must be callable") if itemCheck is not None and not hasattr(itemCheck, "__call__"): raise ValueError("'itemCheck' must be callable") source = getStackFrame() self._setup(doc=doc, dtype=List, default=default, check=None, optional=optional, source=source, deprecated=deprecated) self.listCheck = listCheck """Callable used to check the list as a whole. """ self.itemCheck = itemCheck """Callable used to validate individual items as they are inserted into the list. """ self.itemtype = dtype """Data type of list items. """ self.length = length """Number of items that must be present in the list (or `None` to disable checking the list's length). """ self.minLength = minLength """Minimum number of items that must be present in the list (or `None` to disable checking the list's minimum length). """ self.maxLength = maxLength """Maximum number of items that must be present in the list (or `None`