25 __all__ = [
"getPropertySetState",
"getPropertyListState",
"setPropertySetState",
"setPropertyListState"]
30 from collections.abc
import Mapping, KeysView
34 from .propertySet
import PropertySet
35 from .propertyList
import PropertyList
36 from ..dateTime
import DateTime
40 """Get the state of a PropertySet in a form that can be pickled. 44 container : `PropertySet` 45 The property container. 46 asLists : `bool`, optional 47 If False, the default, `tuple` will be used for the contents. If true 48 a `list` will be used. 52 state : `list` of `tuple` or `list` of `list` 53 The state, as a list of tuples (or lists), each of which contains 54 the following 3 items: 55 - name (a `str`): the name of the item 56 - elementTypeName (a `str`): the suffix of a ``setX`` method name 57 which is appropriate for the data type. For example integer 58 data has ``elementTypeName="Int"` which corresponds to 59 the ``setInt`` method. 60 - value: the data for the item, in a form compatible 61 with the set method named by ``elementTypeName`` 63 names = container.names(topLevelOnly=
True)
64 sequence = list
if asLists
else tuple
65 return [sequence((name, _propertyContainerElementTypeName(container, name),
66 _propertyContainerGet(container, name, returnStyle=ReturnStyle.AUTO)))
71 """Get the state of a PropertyList in a form that can be pickled. 75 container : `PropertyList` 76 The property container. 77 asLists : `bool`, optional 78 If False, the default, `tuple` will be used for the contents. If true 79 a `list` will be used. 83 state : `list` of `tuple` or `list` of `list` 84 The state, as a list of tuples (or lists), each of which contains 85 the following 4 items: 86 - name (a `str`): the name of the item 87 - elementTypeName (a `str`): the suffix of a ``setX`` method name 88 which is appropriate for the data type. For example integer 89 data has ``elementTypeName="Int"` which corresponds to 90 the ``setInt`` method. 91 - value: the data for the item, in a form compatible 92 with the set method named by ``elementTypeName`` 93 - comment (a `str`): the comment. This item is only present 94 if ``container`` is a PropertyList. 96 sequence = list
if asLists
else tuple
97 return [sequence((name, _propertyContainerElementTypeName(container, name),
98 _propertyContainerGet(container, name, returnStyle=ReturnStyle.AUTO),
99 container.getComment(name)))
100 for name
in container.getOrderedNames()]
104 """Restore the state of a PropertySet, in place. 108 container : `PropertySet` 109 The property container whose state is to be restored. 110 It should be empty to start with and is updated in place. 112 The state, as returned by `getPropertySetState` 114 for name, elemType, value
in state:
115 if elemType
is not None:
116 getattr(container,
"set" + elemType)(name, value)
118 raise ValueError(f
"Unrecognized values for state restoration: ({name}, {elemType}, {value})")
122 """Restore the state of a PropertyList, in place. 126 container : `PropertyList` 127 The property container whose state is to be restored. 128 It should be empty to start with and is updated in place. 130 The state, as returned by ``getPropertyListState`` 132 for name, elemType, value, comment
in state:
133 getattr(container,
"set" + elemType)(name, value, comment)
142 def _propertyContainerElementTypeName(container, name):
143 """Return name of the type of a particular element""" 145 t = container.typeOf(name)
150 for checkType
in (
"Bool",
"Short",
"Int",
"Long",
"LongLong",
"Float",
"Double",
"String",
"DateTime",
152 if t == getattr(container,
"TYPE_" + checkType):
157 def _propertyContainerGet(container, name, returnStyle):
158 """Get a value of unknown type as a scalar or array 162 container : `lsst.daf.base.PropertySet` or `lsst.daf.base.PropertyList` 163 Container from which to get the value 166 returnStyle : `ReturnStyle` 167 Control whether numeric or string data is returned as an array 168 or scalar (the other types, ``PropertyList``, ``PropertySet`` 169 and ``PersistablePtr``, are always returned as a scalar): 170 - ReturnStyle.ARRAY: return numeric or string data types 171 as an array of values. 172 - ReturnStyle.SCALAR: return numeric or string data types 173 as a single value; if the item has multiple values then 174 return the last value. 175 - ReturnStyle.AUTO: (deprecated) return numeric or string data 176 as a scalar if there is just one item, or as an array 182 The specified key does not exist in the container. 184 The value retrieved is of an unexpected type. 186 The value for ``returnStyle`` is not correct. 188 if not container.exists(name):
189 raise KeyError(name +
" not found")
190 if returnStyle
not in ReturnStyle:
191 raise ValueError(
"returnStyle {} must be a ReturnStyle".
format(returnStyle))
193 elemType = _propertyContainerElementTypeName(container, name)
194 if elemType
and elemType !=
"PropertySet":
195 value = getattr(container,
"getArray" + elemType)(name)
196 if returnStyle == ReturnStyle.ARRAY
or (returnStyle == ReturnStyle.AUTO
and len(value) > 1):
200 if container.isPropertySetPtr(name):
202 return container.getAsPropertyListPtr(name)
204 return container.getAsPropertySetPtr(name)
206 return container.getAsPersistablePtr(name)
209 raise TypeError(
'Unknown PropertySet value type for ' + name)
212 def _guessIntegerType(container, name, value):
213 """Given an existing container and name, determine the type 214 that should be used for the supplied value. The supplied value 215 is assumed to be a scalar. 217 On Python 3 all ints are LongLong but we need to be able to store them 218 in Int containers if that is what is being used (testing for truncation). 219 Int is assumed to mean 32bit integer (2147483647 to -2147483648). 221 If there is no pre-existing value we have to decide what to do. For now 222 we pick Int if the value is less than maxsize. 224 Returns None if the value supplied is a bool or not an integral value. 232 if isinstance(value, bool):
235 if isinstance(value, numbers.Integral):
237 containerType = _propertyContainerElementTypeName(container, name)
241 if value <= maxInt
and value >= minInt:
246 if containerType ==
"Int":
252 elif containerType ==
"LongLong":
257 def _propertyContainerSet(container, name, value, typeMenu, *args):
258 """Set a single Python value of unknown type""" 259 if hasattr(value,
"__iter__")
and not isinstance(value, (str, PropertySet, PropertyList)):
265 setType = _guessIntegerType(container, name, exemplar)
267 if setType
is not None or t
in typeMenu:
269 setType = typeMenu[t]
270 return getattr(container,
"set" + setType)(name, value, *args)
272 for checkType
in typeMenu:
273 if isinstance(exemplar, checkType):
274 return getattr(container,
"set" + typeMenu[checkType])(name, value, *args)
275 raise TypeError(
"Unknown value type for %s: %s" % (name, t))
278 def _propertyContainerAdd(container, name, value, typeMenu, *args):
279 """Add a single Python value of unknown type""" 280 if hasattr(value,
"__iter__"):
286 addType = _guessIntegerType(container, name, exemplar)
288 if addType
is not None or t
in typeMenu:
290 addType = typeMenu[t]
291 return getattr(container,
"add" + addType)(name, value, *args)
293 for checkType
in typeMenu:
294 if isinstance(exemplar, checkType):
295 return getattr(container,
"add" + typeMenu[checkType])(name, value, *args)
296 raise TypeError(
"Unknown value type for %s: %s" % (name, t))
299 def _makePropertySet(state):
300 """Make a `PropertySet` from the state returned by `getPropertySetState` 305 The data returned by `getPropertySetState`. 312 def _makePropertyList(state):
313 """Make a `PropertyList` from the state returned by 314 `getPropertyListState` 319 The data returned by `getPropertySetState`. 330 _typeMenu = {bool:
"Bool",
333 DateTime:
"DateTime",
334 PropertySet:
"PropertySet",
335 PropertyList:
"PropertySet",
339 """Return an item as a scalar or array 341 Return an array if the item is of numeric or string type and has 342 more than one value, otherwise return a scalar. 344 .. deprecated:: 20180-06 345 `get` is superseded by `getArray` or `getScalar` 355 If the item does not exist. 357 warnings.warn(
"Use getArray or getScalar instead", DeprecationWarning, stacklevel=2)
358 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
361 """Return an item as an array if the item is numeric or string 363 If the item is a `PropertySet`, `PropertyList` or 364 `lsst.daf.base.PersistablePtr` then return the item as a scalar. 374 If the item does not exist. 376 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.ARRAY)
379 """Return an item as a scalar 381 If the item has more than one value then the last value is returned 391 If the item does not exist. 393 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.SCALAR)
395 def set(self, name, value):
396 """Set the value of an item 398 If the item already exists it is silently replaced; the types 405 value : any supported type 406 Value of item; may be a scalar or array 408 return _propertyContainerSet(self, name, value, self.
_typeMenu)
410 def add(self, name, value):
411 """Append one or more values to a given item, which need not exist 413 If the item exists then the new value(s) are appended; 414 otherwise it is like calling `set` 420 value : any supported type 421 Value of item; may be a scalar or array 425 If ``value`` is an `lsst.daf.base.PropertySet` or 426 `lsst.daf.base.PropertyList` then ``value`` replaces 427 the existing value. Also the item is added as a live 428 reference, so updating ``value`` will update this container 433 lsst::pex::exceptions::TypeError 434 If the type of `value` is incompatible with the existing value 437 return _propertyContainerAdd(self, name, value, self.
_typeMenu)
440 """Returns a (possibly nested) dictionary with all properties. 445 Dictionary with all names and values (no comments). 449 for name
in self.names():
450 v = _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
452 if isinstance(v, PropertySet):
453 d[name] = PropertySet.toDict(v)
462 if len(self) != len(other):
466 if _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO) != \
467 _propertyContainerGet(other, name, returnStyle=ReturnStyle.AUTO):
469 if self.typeOf(name) != other.typeOf(name):
477 for itemName
in self:
478 ps.copy(itemName, self, itemName)
482 result = self.deepCopy()
483 memo[
id(self)] = result
488 return name
in self.names(topLevelOnly=
True)
491 if isinstance(value, Mapping):
494 for k, v
in value.items():
497 self.
set(name, value)
503 raise KeyError(f
"{name} not present in dict")
506 return self.toString()
509 return self.nameCount(topLevelOnly=
True)
512 for n
in self.names(topLevelOnly=
True):
516 return KeysView(self)
530 _typeMenu = {bool:
"Bool",
534 DateTime:
"DateTime",
535 PropertySet:
"PropertySet",
536 PropertyList:
"PropertySet",
539 COMMENTSUFFIX =
"#COMMENT" 542 """Return an item as a scalar or array 544 Return an array if the item has more than one value, 545 otherwise return a scalar. 547 .. deprecated:: 20180-06 548 `get` is superseded by `getArray` or `getScalar` 558 If the item does not exist. 560 warnings.warn(
"Use getArray or getScalar instead", DeprecationWarning, stacklevel=2)
561 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
564 """Return an item as an array 574 If the item does not exist. 576 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.ARRAY)
579 """Return an item as a scalar 581 If the item has more than one value then the last value is returned 591 If the item does not exist. 593 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.SCALAR)
595 def set(self, name, value, comment=None):
596 """Set the value of an item 598 If the item already exists it is silently replaced; the types 605 value : any supported type 606 Value of item; may be a scalar or array 609 if comment
is not None:
611 return _propertyContainerSet(self, name, value, self.
_typeMenu, *args)
613 def add(self, name, value, comment=None):
614 """Append one or more values to a given item, which need not exist 616 If the item exists then the new value(s) are appended; 617 otherwise it is like calling `set` 623 value : any supported type 624 Value of item; may be a scalar or array 628 If `value` is an `lsst.daf.base.PropertySet` items are added 629 using dotted names (e.g. if name="a" and value contains 630 an item "b" which is another PropertySet and contains an 631 item "c" which is numeric or string, then the value of "c" 632 is added as "a.b.c", appended to the existing values of 633 "a.b.c" if any (in which case the types must be compatible). 637 lsst::pex::exceptions::TypeError 638 If the type of `value` is incompatible with the existing value 642 if comment
is not None:
644 return _propertyContainerAdd(self, name, value, self.
_typeMenu, *args)
647 """Set the comment for an existing entry. 652 Name of the key to receive updated comment. 658 containerType = _propertyContainerElementTypeName(self, name)
659 if self.isArray(name):
663 getattr(self, f
"set{containerType}")(name, value, comment)
666 """Return a list of tuples of name, value, comment for each property 667 in the order that they were inserted. 671 ret : `list` of `tuple` 672 Tuples of name, value, comment for each property in the order 673 in which they were inserted. 675 orderedNames = self.getOrderedNames()
677 for name
in orderedNames:
678 if self.isArray(name):
679 values = _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
681 ret.append((name, v, self.getComment(name)))
683 ret.append((name, _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO),
684 self.getComment(name)))
688 """Return an ordered dictionary with all properties in the order that 693 d : `~collections.OrderedDict` 694 Ordered dictionary with all properties in the order that they 695 were inserted. Comments are not included. 697 from collections
import OrderedDict
700 for name
in self.getOrderedNames():
701 d[name] = _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
708 if not PropertySet.__eq__(self, other):
712 if self.getComment(name) != other.getComment(name):
720 for itemName
in self:
721 pl.copy(itemName, self, itemName)
725 result = self.deepCopy()
726 memo[
id(self)] = result
730 for n
in self.getOrderedNames():
738 if isinstance(value, Mapping):
741 for k, v
in value.items():
744 self.
set(name, value)
def __contains__(self, name)
def add(self, name, value, comment=None)
def set(self, name, value, comment=None)
def __deepcopy__(self, memo)
def set(self, name, value)
def __setitem__(self, name, value)
def add(self, name, value)
def getPropertySetState(container, asLists=False)
def setComment(self, name, comment)
def __setitem__(self, name, value)
def getScalar(self, name)
def setPropertyListState(container, state)
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
def __deepcopy__(self, memo)
def getPropertyListState(container, asLists=False)
def setPropertySetState(container, state)
def __delitem__(self, name)
def getScalar(self, name)