28__all__ = [
"ListField"]
33from typing
import Any, Generic, Iterable, MutableSequence, Union, overload
35from .callStack
import getCallStack, getStackFrame
36from .comparison
import compareScalars, getComparisonName
42 UnexpectedProxyUsageError,
48if int(sys.version_info.minor) < 9:
49 _bases = (collections.abc.MutableSequence, Generic[FieldTypeVar])
51 _bases = (collections.abc.MutableSequence[FieldTypeVar],)
55 """List collection used internally by `ListField`.
60 Config instance that contains the ``field``.
62 Instance of the `ListField` using this ``List``.
64 Sequence of values that are inserted into this ``List``.
66 The call stack (created by `lsst.pex.config.callStack.getCallStack`).
68 Event label for the history.
69 setHistory : `bool`, optional
70 Enable setting the field
's history, using the value of the ``at``
71 parameter. Default is `
True`.
76 Raised
if an item
in the ``value`` parameter does
not have the
77 appropriate type
for this field
or does
not pass the
78 `ListField.itemCheck` method of the ``field`` parameter.
81 def __init__(self, config, field, value, at, label, setHistory=True):
83 self.
_config__config_ = weakref.ref(config)
89 for i, x
in enumerate(value):
90 self.
insertinsert(i, x, setHistory=
False)
92 msg =
"Value %s is of incorrect type %s. Sequence type expected" % (value, _typeStr(value))
98 def _config(self) -> Config:
102 assert value
is not None
106 """Validate an item to determine if it can be included in the list.
111 Index of the item in the `list`.
118 Raised
if an item
in the ``value`` parameter does
not have the
119 appropriate type
for this field
or does
not pass the field
's
120 `ListField.itemCheck` method.
123 if not isinstance(x, self.
_field_field.itemtype)
and x
is not None:
124 msg =
"Item at position %d with value %s is of incorrect type %s. Expected %s" % (
128 _typeStr(self.
_field_field.itemtype),
132 if self.
_field_field.itemCheck
is not None and not self.
_field_field.itemCheck(x):
133 msg =
"Item at position %d is not a valid value: %s" % (i, x)
137 """Sequence of items contained by the `List` (`list`)."""
138 return self.
_list_list
140 history = property(
lambda x: x._history)
141 """Read-only history.
145 return x
in self.
_list_list
148 return len(self.
_list_list)
152 self, i: int, x: FieldTypeVar, at: Any =
None, label: str =
"setitem", setHistory: bool =
True
160 x: Iterable[FieldTypeVar],
162 label: str =
"setitem",
163 setHistory: bool =
True,
167 def __setitem__(self, i, x, at=None, label="setitem", setHistory=True):
168 if self.
_config_config._frozen:
170 if isinstance(i, slice):
171 k, stop, step = i.indices(len(self))
172 for j, xj
in enumerate(x):
173 xj = _autocast(xj, self.
_field_field.itemtype)
178 x = _autocast(x, self.
_field_field.itemtype)
181 self.
_list_list[i] = x
196 return self.
_list_list[i]
198 def __delitem__(self, i, at=None, label="delitem", setHistory=True):
199 if self.
_config_config._frozen:
201 del self.
_list_list[i]
210 def insert(self, i, x, at=None, label="insert", setHistory=True):
211 """Insert an item into the list at the given index.
216 Index where the item is inserted.
218 Item that
is inserted.
220 The call stack (created by
221 `lsst.pex.config.callStack.getCallStack`).
222 label : `str`, optional
223 Event label
for the history.
224 setHistory : `bool`, optional
225 Enable setting the field
's history, using the value of the ``at``
226 parameter. Default is `
True`.
233 return repr(self.
_list_list)
240 if len(self) != len(other):
243 for i, j
in zip(self, other):
247 except AttributeError:
252 return not self.
__eq____eq__(other)
255 if hasattr(getattr(self.__class__, attr,
None),
"__set__"):
257 object.__setattr__(self, attr, value)
258 elif attr
in self.__dict__
or attr
in [
"_field",
"_config_",
"_history",
"_list",
"__doc__"]:
260 object.__setattr__(self, attr, value)
263 msg =
"%s has no attribute %s" % (_typeStr(self.
_field_field), attr)
268 f
"Proxy container for config field {self._field.name} cannot "
269 "be pickled; it should be converted to a built-in container before "
270 "being assigned to other objects or variables."
275 """A configuration field (`~lsst.pex.config.Field` subclass) that contains
276 a list of values of a specific type.
281 A description of the field.
282 dtype : class, optional
283 The data type of items
in the list. Optional
if supplied
as typing
284 argument to the
class.
285 default : sequence, optional
286 The default items
for the field.
287 optional : `bool`, optional
288 Set whether the field
is *optional*. When `
False`,
289 `lsst.pex.config.Config.validate` will fail
if the field
's value is
291 listCheck : callable, optional
292 A callable that validates the list
as a whole.
293 itemCheck : callable, optional
294 A callable that validates individual items
in the list.
295 length : `int`, optional
296 If set, this field must contain exactly ``length`` number of items.
297 minLength : `int`, optional
298 If set, this field must contain *at least* ``minLength`` number of
300 maxLength : `int`, optional
301 If set, this field must contain *no more than* ``maxLength`` number of
303 deprecated :
None or `str`, optional
304 A description of why this Field
is deprecated, including removal date.
305 If
not None, the string
is appended to the docstring
for this Field.
335 "dtype must either be supplied as an argument or as a type argument to the class"
337 if dtype
not in Field.supportedTypes:
338 raise ValueError(
"Unsupported dtype %s" % _typeStr(dtype))
339 if length
is not None:
341 raise ValueError(
"'length' (%d) must be positive" % length)
345 if maxLength
is not None and maxLength <= 0:
346 raise ValueError(
"'maxLength' (%d) must be positive" % maxLength)
347 if minLength
is not None and maxLength
is not None and minLength > maxLength:
349 "'maxLength' (%d) must be at least"
350 " as large as 'minLength' (%d)" % (maxLength, minLength)
353 if listCheck
is not None and not hasattr(listCheck,
"__call__"):
354 raise ValueError(
"'listCheck' must be callable")
355 if itemCheck
is not None and not hasattr(itemCheck,
"__call__"):
356 raise ValueError(
"'itemCheck' must be callable")
366 deprecated=deprecated,
370 """Callable used to check the list as a whole.
374 """Callable used to validate individual items as they are inserted
379 """Data type of list items.
383 """Number of items that must be present in the list (or `None` to
384 disable checking the list's length).
388 """Minimum number of items that must be present in the list (or `None`
389 to disable checking the list's minimum length).
393 """Maximum number of items that must be present in the list (or `None`
394 to disable checking the list's maximum length).
398 """Validate the field.
403 The config instance that contains this field.
410 - The field
is not optional, but the value
is `
None`.
411 - The list itself does
not meet the requirements of the `length`,
412 `minLength`,
or `maxLength` attributes.
413 - The `listCheck` callable returns `
False`.
417 Individual item checks (`itemCheck`) are applied when each item
is
418 set
and are
not re-checked by this method.
420 Field.validate(self, instance)
422 if value
is not None:
423 lenValue = len(value)
424 if self.
lengthlength
is not None and not lenValue == self.
lengthlength:
425 msg =
"Required list length=%d, got length=%d" % (self.
lengthlength, lenValue)
428 msg =
"Minimum allowed list length=%d, got length=%d" % (self.
minLengthminLength, lenValue)
431 msg =
"Maximum allowed list length=%d, got length=%d" % (self.
maxLengthmaxLength, lenValue)
434 msg =
"%s is not a valid value" %
str(value)
440 value: Union[Iterable[FieldTypeVar],
None],
442 label: str =
"assignment",
450 if value
is not None:
451 value =
List(instance, self, value, at, label)
453 history = instance._history.setdefault(self.name, [])
454 history.append((value, at, label))
456 instance._storage[self.name] = value
459 """Convert the value of this field to a plain `list`.
461 `lsst.pex.config.Config.toDict` is the primary user of this method.
466 The config instance that contains this field.
471 Plain `list` of items,
or `
None`
if the field
is not set.
474 return list(value)
if value
is not None else None
476 def _compare(self, instance1, instance2, shortcut, rtol, atol, output):
477 """Compare two config instances for equality with respect to this
480 `lsst.pex.config.config.compare` is the primary user of this method.
491 If `
True`,
return as soon
as an **inequality**
is found.
493 Relative tolerance
for floating point comparisons.
495 Absolute tolerance
for floating point comparisons.
497 If
not None, a callable that takes a `str`, used (possibly
498 repeatedly) to report inequalities.
503 `
True`
if the fields are equal; `
False` otherwise.
507 Floating point comparisons are performed by `numpy.allclose`.
509 l1 = getattr(instance1, self.name)
510 l2 = getattr(instance2, self.name)
512 _joinNamePath(instance1._name, self.name), _joinNamePath(instance2._name, self.name)
514 if not compareScalars(
"isnone for %s" % name, l1
is None, l2
is None, output=output):
516 if l1
is None and l2
is None:
518 if not compareScalars(
"size for %s" % name, len(l1), len(l2), output=output):
521 for n, v1, v2
in zip(range(len(l1)), l1, l2):
523 "%s[%d]" % (name, n), v1, v2, dtype=self.
dtypedtype, rtol=rtol, atol=atol, output=output
525 if not result
and shortcut:
527 equal = equal
and result
"Field[FieldTypeVar]" __get__(self, None instance, Any owner=None, Any at=None, str label="default")
def __get__(self, instance, owner=None, at=None, label="default")
FieldTypeVar __get__(self, "Config" instance, Any owner=None, Any at=None, str label="default")
def _setup(self, doc, dtype, default, check, optional, source, deprecated)
def __init__(self, doc, dtype=None, default=None, optional=False, listCheck=None, itemCheck=None, length=None, minLength=None, maxLength=None, deprecated=None)
None __set__(self, Config instance, Union[Iterable[FieldTypeVar], None] value, Any at=None, str label="assignment")
def toDict(self, instance)
def validate(self, instance)
def __delitem__(self, i, at=None, label="delitem", setHistory=True)
None __setitem__(self, slice i, Iterable[FieldTypeVar] x, Any at=None, str label="setitem", bool setHistory=True)
FieldTypeVar __getitem__(self, int i)
None __setitem__(self, int i, FieldTypeVar x, Any at=None, str label="setitem", bool setHistory=True)
def __setattr__(self, attr, value, at=None, label="assignment")
def __contains__(self, x)
def __init__(self, config, field, value, at, label, setHistory=True)
def insert(self, i, x, at=None, label="insert", setHistory=True)
def __setitem__(self, i, x, at=None, label="setitem", setHistory=True)
def validateItem(self, i, x)
std::shared_ptr< FrameSet > append(FrameSet const &first, FrameSet const &second)
Construct a FrameSet that performs two transformations in series.
def getStackFrame(relative=0)
def compareScalars(name, v1, v2, output, rtol=1e-8, atol=1e-8, dtype=None)
def getComparisonName(name1, name2)