25 __all__ = [
"getstate",
"setstate"]
33 from .propertySet
import PropertySet
34 from .propertyList
import PropertyList
37 from ..dateTime
import DateTime
46 def _propertyContainerElementTypeName(container, name):
47 """Return name of the type of a particular element""" 48 t = container.typeOf(name)
49 for checkType
in (
"Bool",
"Short",
"Int",
"Long",
"LongLong",
"Float",
"Double",
"String",
"DateTime"):
50 if t == getattr(container,
"TYPE_" + checkType):
55 def _propertyContainerGet(container, name, returnStyle):
56 """Get a value of unknown type as a scalar or array 60 container : ``lsst.daf.base.PropertySet`` or ``lsst.daf.base.PropertyList`` 61 Container from which to get the value 64 returnStyle : ``ReturnStyle`` 65 Control whether data is returned as an array or scalar: 66 - ReturnStyle.ARRAY: return numeric or string data types 67 as an array of values. Raise TypeError for 68 PropertyList, PropertySet or PersistablePtr. 69 - ReturnStyle.SCALAR: return numeric or string data types 70 as a single value; if the item has multiple values then 71 return the last value. Return PropertyList, PropertySet 72 or PersistablePtr as a single item. 73 - ReturnStyle.AUTO: (deprecated) return numeric or string data 74 as a scalar if there is just one item, or as an array 75 otherwise. Return PropertyList, PropertySet 76 or PersistablePtr as a single item. 81 If `returnStyle`=``ReturnStyle.ARRAY`` and the item is of type 82 ``PropertyList``, ``PropertySet`` or ``PersistablePtr`` 86 `returnStyle` is handled as follows: 88 if not container.exists(name):
90 if returnStyle
not in ReturnStyle:
91 raise ValueError(
"returnStyle {} must be a ReturnStyle".format(returnStyle))
93 elemType = _propertyContainerElementTypeName(container, name)
95 value = getattr(container,
"getArray" + elemType)(name)
96 if returnStyle == ReturnStyle.ARRAY
or (returnStyle == ReturnStyle.AUTO
and len(value) > 1):
100 if returnStyle == ReturnStyle.ARRAY:
101 raise TypeError(
"Item {} is not numeric or string".format(name))
104 return container.getAsPropertyListPtr(name)
107 if container.typeOf(name) == container.TYPE_PropertySet:
108 return container.getAsPropertySetPtr(name)
110 return container.getAsPersistablePtr(name)
116 def _guessIntegerType(container, name, value):
117 """Given an existing container and name, determine the type 118 that should be used for the supplied value. The supplied value 119 is assumed to be a scalar. 121 On Python 3 all ints are LongLong but we need to be able to store them 122 in Int containers if that is what is being used (testing for truncation). 123 Int is assumed to mean 32bit integer (2147483647 to -2147483648). 125 If there is no pre-existing value we have to decide what to do. For now 126 we pick Int if the value is less than maxsize. 128 Returns None if the value supplied is a bool or not an integral value. 136 if isinstance(value, bool):
139 if isinstance(value, numbers.Integral):
141 containerType = _propertyContainerElementTypeName(container, name)
145 if value <= maxInt
and value >= minInt:
150 if containerType ==
"Int":
156 elif containerType ==
"LongLong":
161 def _propertyContainerSet(container, name, value, typeMenu, *args):
162 """Set a single Python value of unknown type""" 163 if hasattr(value,
"__iter__")
and not isinstance(value, str):
169 setType = _guessIntegerType(container, name, exemplar)
171 if setType
is not None or t
in typeMenu:
173 setType = typeMenu[t]
174 return getattr(container,
"set" + setType)(name, value, *args)
176 for checkType
in typeMenu:
177 if isinstance(exemplar, checkType):
178 return getattr(container,
"set" + typeMenu[checkType])(name, value, *args)
182 def _propertyContainerAdd(container, name, value, typeMenu, *args):
183 """Add a single Python value of unknown type""" 184 if hasattr(value,
"__iter__"):
190 addType = _guessIntegerType(container, name, exemplar)
192 if addType
is not None or t
in typeMenu:
194 addType = typeMenu[t]
195 return getattr(container,
"add" + addType)(name, value, *args)
197 for checkType
in typeMenu:
198 if isinstance(exemplar, checkType):
199 return getattr(container,
"add" + typeMenu[checkType])(name, value, *args)
204 return [(name, _propertyContainerElementTypeName(self, name),
205 _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO),
206 self.getComment(name))
for name
in self.getOrderedNames()]
210 for name, elemType, value, comment
in state:
211 getattr(self,
"set" + elemType)(name, value, comment)
218 _typeMenu = {bool:
"Bool",
221 DateTime:
"DateTime",
222 PropertySet:
"PropertySet",
223 PropertyList:
"PropertySet",
229 _typeMenu[unicode] =
"String" 234 """Return an item as a scalar or array 236 Return an array if the item is of numeric or string type and has 237 more than one value, otherwise return a scalar. 239 .. deprecated:: 20180-06 240 `get` is superseded by `getArray` or `getScalar` 249 lsst.pex.exceptions.NotFoundError 250 If the item does not exist. 252 warnings.warn(
"Use getArray or getScalar instead", DeprecationWarning, stacklevel=2)
253 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
256 """Return an item as an array; the item type must be numeric or string 265 lsst.pex.exceptions.NotFoundError 266 If the item does not exist. 268 If item type is ``lsst.daf.base.PropertyList``, 269 ``lsst.daf.base.PropertySet`` 270 or ``lsst.daf.base.PersistablePtr``. 272 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.ARRAY)
275 """Return an item as a scalar 277 If the item has more than one value then the last value is returned 286 lsst.pex.exceptions.NotFoundError 287 If the item does not exist. 289 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.SCALAR)
291 def set(self, name, value):
292 """Set the value of an item 294 If the item already exists it is silently replaced; the types 301 value : any supported type 302 Value of item; may be a scalar or array 304 return _propertyContainerSet(self, name, value, self.
_typeMenu)
306 def add(self, name, value):
307 """Append one or more values to a given item, which need not exist 309 If the item exists then the new value(s) are appended; 310 otherwise it is like calling `set` 316 value : any supported type 317 Value of item; may be a scalar or array 321 If `value` is an ``lsst.daf.base.PropertySet`` or 322 ``lsst.daf.base.PropertyList`` then `value` replaces 323 the existing value. Also the item is added as a live 324 reference, so updating `value` will update this container 329 lsst::pex::exceptions::TypeError 330 If the type of `value` is incompatible with the existing value 333 return _propertyContainerAdd(self, name, value, self.
_typeMenu)
336 """Returns a (possibly nested) dictionary with all properties. 340 for name
in self.names():
341 v = _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
343 if isinstance(v, PropertySet):
344 d[name] = PropertySet.toDict(v)
353 _typeMenu = {bool:
"Bool",
357 DateTime:
"DateTime",
358 PropertySet:
"PropertySet",
359 PropertyList:
"PropertySet",
365 _typeMenu[unicode] =
"String" 370 """Return an item as a scalar or array 372 Return an array if the item has more than one value, 373 otherwise return a scalar. 375 .. deprecated:: 20180-06 376 `get` is superseded by `getArray` or `getScalar` 385 lsst.pex.exceptions.NotFoundError 386 If the item does not exist. 388 warnings.warn(
"Use getArray or getScalar instead", DeprecationWarning, stacklevel=2)
389 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
392 """Return an item as an array 401 lsst.pex.exceptions.NotFoundError 402 If the item does not exist. 404 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.ARRAY)
407 """Return an item as a scalar 409 If the item has more than one value then the last value is returned 418 lsst.pex.exceptions.NotFoundError 419 If the item does not exist. 421 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.SCALAR)
423 def set(self, name, value, comment=None):
424 """Set the value of an item 426 If the item already exists it is silently replaced; the types 433 value : any supported type 434 Value of item; may be a scalar or array 437 if comment
is not None:
439 return _propertyContainerSet(self, name, value, self.
_typeMenu, *args)
441 def add(self, name, value, comment=None):
442 """Append one or more values to a given item, which need not exist 444 If the item exists then the new value(s) are appended; 445 otherwise it is like calling `set` 451 value : any supported type 452 Value of item; may be a scalar or array 456 If `value` is an ``lsst.daf.base.PropertySet`` items are added 457 using dotted names (e.g. if name="a" and value contains 458 an item "b" which is another PropertySet and contains an 459 item "c" which is numeric or string, then the value of "c" 460 is added as "a.b.c", appended to the existing values of 461 "a.b.c" if any (in which case the types must be compatible). 465 lsst::pex::exceptions::TypeError 466 If the type of `value` is incompatible with the existing value 470 if comment
is not None:
472 return _propertyContainerAdd(self, name, value, self.
_typeMenu, *args)
475 orderedNames = self.getOrderedNames()
477 for name
in orderedNames:
478 if self.isArray(name):
479 values = _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
481 ret.append((name, v, self.getComment(name)))
483 ret.append((name, _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO),
484 self.getComment(name)))
488 """Return an ordered dictionary with all properties in the order that 491 from collections
import OrderedDict
494 for name
in self.getOrderedNames():
495 d[name] = _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
def setstate(self, state)
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 getScalar(self, name)