25 __all__ = [
"getPropertySetState",
"getPropertyListState",
"setPropertySetState",
"setPropertyListState"]
33 from .propertySet
import PropertySet
34 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. 50 The state, as a list of tuples, each of which contains 51 the following 3 items: 52 - name (a `str`): the name of the item 53 - elementTypeName (a `str`): the suffix of a ``setX`` method name 54 which is appropriate for the data type. For example integer 55 data has ``elementTypeName="Int"` which corresponds to 56 the ``setInt`` method. 57 - value: the data for the item, in a form compatible 58 with the set method named by ``elementTypeName`` 60 return [(name, _propertyContainerElementTypeName(container, name),
61 _propertyContainerGet(container, name, returnStyle=ReturnStyle.AUTO))
62 for name
in container.paramNames(
False)]
66 """Get the state of a PropertyList in a form that can be pickled. 70 container : `PropertyList` 71 The property container. 76 The state, as a list of tuples, each of which contains 77 the following 4 items: 78 - name (a `str`): the name of the item 79 - elementTypeName (a `str`): the suffix of a ``setX`` method name 80 which is appropriate for the data type. For example integer 81 data has ``elementTypeName="Int"` which corresponds to 82 the ``setInt`` method. 83 - value: the data for the item, in a form compatible 84 with the set method named by ``elementTypeName`` 85 - comment (a `str`): the comment. This item is only present 86 if ``container`` is a PropertyList. 88 return [(name, _propertyContainerElementTypeName(container, name),
89 _propertyContainerGet(container, name, returnStyle=ReturnStyle.AUTO),
90 container.getComment(name))
91 for name
in container.getOrderedNames()]
95 """Restore the state of a PropertySet, in place. 99 container : `PropertySet` 100 The property container whose state is to be restored. 101 It should be empty to start with and is updated in place. 103 The state, as returned by ``getPropertySetState`` 105 for name, elemType, value
in state:
106 getattr(container,
"set" + elemType)(name, value)
110 """Restore the state of a PropertyList, in place. 114 container : `PropertyList` 115 The property container whose state is to be restored. 116 It should be empty to start with and is updated in place. 118 The state, as returned by ``getPropertyListState`` 120 for name, elemType, value, comment
in state:
121 getattr(container,
"set" + elemType)(name, value, comment)
130 def _propertyContainerElementTypeName(container, name):
131 """Return name of the type of a particular element""" 132 t = container.typeOf(name)
133 for checkType
in (
"Bool",
"Short",
"Int",
"Long",
"LongLong",
"Float",
"Double",
"String",
"DateTime"):
134 if t == getattr(container,
"TYPE_" + checkType):
139 def _propertyContainerGet(container, name, returnStyle):
140 """Get a value of unknown type as a scalar or array 144 container : ``lsst.daf.base.PropertySet`` or ``lsst.daf.base.PropertyList`` 145 Container from which to get the value 148 returnStyle : ``ReturnStyle`` 149 Control whether numeric or string data is returned as an array 150 or scalar (the other types, ``PropertyList``, ``PropertySet`` 151 and ``PersistablePtr``, are always returned as a scalar): 152 - ReturnStyle.ARRAY: return numeric or string data types 153 as an array of values. 154 - ReturnStyle.SCALAR: return numeric or string data types 155 as a single value; if the item has multiple values then 156 return the last value. 157 - ReturnStyle.AUTO: (deprecated) return numeric or string data 158 as a scalar if there is just one item, or as an array 161 if not container.exists(name):
163 if returnStyle
not in ReturnStyle:
164 raise ValueError(
"returnStyle {} must be a ReturnStyle".format(returnStyle))
166 elemType = _propertyContainerElementTypeName(container, name)
168 value = getattr(container,
"getArray" + elemType)(name)
169 if returnStyle == ReturnStyle.ARRAY
or (returnStyle == ReturnStyle.AUTO
and len(value) > 1):
174 return container.getAsPropertyListPtr(name)
177 if container.typeOf(name) == container.TYPE_PropertySet:
178 return container.getAsPropertySetPtr(name)
180 return container.getAsPersistablePtr(name)
186 def _guessIntegerType(container, name, value):
187 """Given an existing container and name, determine the type 188 that should be used for the supplied value. The supplied value 189 is assumed to be a scalar. 191 On Python 3 all ints are LongLong but we need to be able to store them 192 in Int containers if that is what is being used (testing for truncation). 193 Int is assumed to mean 32bit integer (2147483647 to -2147483648). 195 If there is no pre-existing value we have to decide what to do. For now 196 we pick Int if the value is less than maxsize. 198 Returns None if the value supplied is a bool or not an integral value. 206 if isinstance(value, bool):
209 if isinstance(value, numbers.Integral):
211 containerType = _propertyContainerElementTypeName(container, name)
215 if value <= maxInt
and value >= minInt:
220 if containerType ==
"Int":
226 elif containerType ==
"LongLong":
231 def _propertyContainerSet(container, name, value, typeMenu, *args):
232 """Set a single Python value of unknown type""" 233 if hasattr(value,
"__iter__")
and not isinstance(value, str):
239 setType = _guessIntegerType(container, name, exemplar)
241 if setType
is not None or t
in typeMenu:
243 setType = typeMenu[t]
244 return getattr(container,
"set" + setType)(name, value, *args)
246 for checkType
in typeMenu:
247 if isinstance(exemplar, checkType):
248 return getattr(container,
"set" + typeMenu[checkType])(name, value, *args)
252 def _propertyContainerAdd(container, name, value, typeMenu, *args):
253 """Add a single Python value of unknown type""" 254 if hasattr(value,
"__iter__"):
260 addType = _guessIntegerType(container, name, exemplar)
262 if addType
is not None or t
in typeMenu:
264 addType = typeMenu[t]
265 return getattr(container,
"add" + addType)(name, value, *args)
267 for checkType
in typeMenu:
268 if isinstance(exemplar, checkType):
269 return getattr(container,
"add" + typeMenu[checkType])(name, value, *args)
273 def _makePropertySet(state):
274 """Make a ``PropertySet`` from the state returned by ``getstate`` 279 The data returned by ``getstate``. 286 def _makePropertyList(state):
287 """Make a ``PropertyList`` from the state returned by ``getstate`` 292 The data returned by ``getstate``. 303 _typeMenu = {bool:
"Bool",
306 DateTime:
"DateTime",
307 PropertySet:
"PropertySet",
308 PropertyList:
"PropertySet",
314 _typeMenu[unicode] =
"String" 319 """Return an item as a scalar or array 321 Return an array if the item is of numeric or string type and has 322 more than one value, otherwise return a scalar. 324 .. deprecated:: 20180-06 325 `get` is superseded by `getArray` or `getScalar` 334 lsst.pex.exceptions.NotFoundError 335 If the item does not exist. 337 warnings.warn(
"Use getArray or getScalar instead", DeprecationWarning, stacklevel=2)
338 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
341 """Return an item as an array if the item is numeric or string 343 If the item is a ``PropertySet``, ``PropertyList`` or 344 ``lsst.daf.base.PersistablePtr`` then return the item as a scalar. 353 lsst.pex.exceptions.NotFoundError 354 If the item does not exist. 356 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.ARRAY)
359 """Return an item as a scalar 361 If the item has more than one value then the last value is returned 370 lsst.pex.exceptions.NotFoundError 371 If the item does not exist. 373 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.SCALAR)
375 def set(self, name, value):
376 """Set the value of an item 378 If the item already exists it is silently replaced; the types 385 value : any supported type 386 Value of item; may be a scalar or array 388 return _propertyContainerSet(self, name, value, self.
_typeMenu)
390 def add(self, name, value):
391 """Append one or more values to a given item, which need not exist 393 If the item exists then the new value(s) are appended; 394 otherwise it is like calling `set` 400 value : any supported type 401 Value of item; may be a scalar or array 405 If `value` is an ``lsst.daf.base.PropertySet`` or 406 ``lsst.daf.base.PropertyList`` then `value` replaces 407 the existing value. Also the item is added as a live 408 reference, so updating `value` will update this container 413 lsst::pex::exceptions::TypeError 414 If the type of `value` is incompatible with the existing value 417 return _propertyContainerAdd(self, name, value, self.
_typeMenu)
420 """Returns a (possibly nested) dictionary with all properties. 424 for name
in self.names():
425 v = _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
427 if isinstance(v, PropertySet):
428 d[name] = PropertySet.toDict(v)
445 _typeMenu = {bool:
"Bool",
449 DateTime:
"DateTime",
450 PropertySet:
"PropertySet",
451 PropertyList:
"PropertySet",
457 _typeMenu[unicode] =
"String" 462 """Return an item as a scalar or array 464 Return an array if the item has more than one value, 465 otherwise return a scalar. 467 .. deprecated:: 20180-06 468 `get` is superseded by `getArray` or `getScalar` 477 lsst.pex.exceptions.NotFoundError 478 If the item does not exist. 480 warnings.warn(
"Use getArray or getScalar instead", DeprecationWarning, stacklevel=2)
481 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
484 """Return an item as an array 493 lsst.pex.exceptions.NotFoundError 494 If the item does not exist. 496 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.ARRAY)
499 """Return an item as a scalar 501 If the item has more than one value then the last value is returned 510 lsst.pex.exceptions.NotFoundError 511 If the item does not exist. 513 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.SCALAR)
515 def set(self, name, value, comment=None):
516 """Set the value of an item 518 If the item already exists it is silently replaced; the types 525 value : any supported type 526 Value of item; may be a scalar or array 529 if comment
is not None:
531 return _propertyContainerSet(self, name, value, self.
_typeMenu, *args)
533 def add(self, name, value, comment=None):
534 """Append one or more values to a given item, which need not exist 536 If the item exists then the new value(s) are appended; 537 otherwise it is like calling `set` 543 value : any supported type 544 Value of item; may be a scalar or array 548 If `value` is an ``lsst.daf.base.PropertySet`` items are added 549 using dotted names (e.g. if name="a" and value contains 550 an item "b" which is another PropertySet and contains an 551 item "c" which is numeric or string, then the value of "c" 552 is added as "a.b.c", appended to the existing values of 553 "a.b.c" if any (in which case the types must be compatible). 557 lsst::pex::exceptions::TypeError 558 If the type of `value` is incompatible with the existing value 562 if comment
is not None:
564 return _propertyContainerAdd(self, name, value, self.
_typeMenu, *args)
567 orderedNames = self.getOrderedNames()
569 for name
in orderedNames:
570 if self.isArray(name):
571 values = _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
573 ret.append((name, v, self.getComment(name)))
575 ret.append((name, _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO),
576 self.getComment(name)))
580 """Return an ordered dictionary with all properties in the order that 583 from collections
import OrderedDict
586 for name
in self.getOrderedNames():
587 d[name] = _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
def add(self, name, value, comment=None)
def set(self, name, value, comment=None)
def set(self, name, value)
def add(self, name, value)
def getScalar(self, name)
def setPropertyListState(container, state)
def setPropertySetState(container, state)
def getPropertySetState(container)
def getScalar(self, name)
def getPropertyListState(container)