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 numeric or string data is returned as an array 66 or scalar (the other types, ``PropertyList``, ``PropertySet`` 67 and ``PersistablePtr``, are always returned as a scalar): 68 - ReturnStyle.ARRAY: return numeric or string data types 69 as an array of values. 70 - ReturnStyle.SCALAR: return numeric or string data types 71 as a single value; if the item has multiple values then 72 return the last value. 73 - ReturnStyle.AUTO: (deprecated) return numeric or string data 74 as a scalar if there is just one item, or as an array 77 if not container.exists(name):
79 if returnStyle
not in ReturnStyle:
80 raise ValueError(
"returnStyle {} must be a ReturnStyle".format(returnStyle))
82 elemType = _propertyContainerElementTypeName(container, name)
84 value = getattr(container,
"getArray" + elemType)(name)
85 if returnStyle == ReturnStyle.ARRAY
or (returnStyle == ReturnStyle.AUTO
and len(value) > 1):
90 return container.getAsPropertyListPtr(name)
93 if container.typeOf(name) == container.TYPE_PropertySet:
94 return container.getAsPropertySetPtr(name)
96 return container.getAsPersistablePtr(name)
102 def _guessIntegerType(container, name, value):
103 """Given an existing container and name, determine the type 104 that should be used for the supplied value. The supplied value 105 is assumed to be a scalar. 107 On Python 3 all ints are LongLong but we need to be able to store them 108 in Int containers if that is what is being used (testing for truncation). 109 Int is assumed to mean 32bit integer (2147483647 to -2147483648). 111 If there is no pre-existing value we have to decide what to do. For now 112 we pick Int if the value is less than maxsize. 114 Returns None if the value supplied is a bool or not an integral value. 122 if isinstance(value, bool):
125 if isinstance(value, numbers.Integral):
127 containerType = _propertyContainerElementTypeName(container, name)
131 if value <= maxInt
and value >= minInt:
136 if containerType ==
"Int":
142 elif containerType ==
"LongLong":
147 def _propertyContainerSet(container, name, value, typeMenu, *args):
148 """Set a single Python value of unknown type""" 149 if hasattr(value,
"__iter__")
and not isinstance(value, str):
155 setType = _guessIntegerType(container, name, exemplar)
157 if setType
is not None or t
in typeMenu:
159 setType = typeMenu[t]
160 return getattr(container,
"set" + setType)(name, value, *args)
162 for checkType
in typeMenu:
163 if isinstance(exemplar, checkType):
164 return getattr(container,
"set" + typeMenu[checkType])(name, value, *args)
168 def _propertyContainerAdd(container, name, value, typeMenu, *args):
169 """Add a single Python value of unknown type""" 170 if hasattr(value,
"__iter__"):
176 addType = _guessIntegerType(container, name, exemplar)
178 if addType
is not None or t
in typeMenu:
180 addType = typeMenu[t]
181 return getattr(container,
"add" + addType)(name, value, *args)
183 for checkType
in typeMenu:
184 if isinstance(exemplar, checkType):
185 return getattr(container,
"add" + typeMenu[checkType])(name, value, *args)
190 if isinstance(self, PropertyList):
191 return [(name, _propertyContainerElementTypeName(self, name),
192 _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO),
193 self.getComment(name))
194 for name
in self.getOrderedNames()]
196 return [(name, _propertyContainerElementTypeName(self, name),
197 _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO))
198 for name
in self.paramNames(
False)]
202 if isinstance(self, PropertyList):
203 for name, elemType, value, comment
in state:
204 getattr(self,
"set" + elemType)(name, value, comment)
206 for name, elemType, value
in state:
207 getattr(self,
"set" + elemType)(name, value)
214 _typeMenu = {bool:
"Bool",
217 DateTime:
"DateTime",
218 PropertySet:
"PropertySet",
219 PropertyList:
"PropertySet",
225 _typeMenu[unicode] =
"String" 230 """Return an item as a scalar or array 232 Return an array if the item is of numeric or string type and has 233 more than one value, otherwise return a scalar. 235 .. deprecated:: 20180-06 236 `get` is superseded by `getArray` or `getScalar` 245 lsst.pex.exceptions.NotFoundError 246 If the item does not exist. 248 warnings.warn(
"Use getArray or getScalar instead", DeprecationWarning, stacklevel=2)
249 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
252 """Return an item as an array if the item is numeric or string 254 If the item is a ``PropertySet``, ``PropertyList`` or 255 ``lsst.daf.base.PersistablePtr`` then return the item as a scalar. 264 lsst.pex.exceptions.NotFoundError 265 If the item does not exist. 267 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.ARRAY)
270 """Return an item as a scalar 272 If the item has more than one value then the last value is returned 281 lsst.pex.exceptions.NotFoundError 282 If the item does not exist. 284 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.SCALAR)
286 def set(self, name, value):
287 """Set the value of an item 289 If the item already exists it is silently replaced; the types 296 value : any supported type 297 Value of item; may be a scalar or array 299 return _propertyContainerSet(self, name, value, self.
_typeMenu)
301 def add(self, name, value):
302 """Append one or more values to a given item, which need not exist 304 If the item exists then the new value(s) are appended; 305 otherwise it is like calling `set` 311 value : any supported type 312 Value of item; may be a scalar or array 316 If `value` is an ``lsst.daf.base.PropertySet`` or 317 ``lsst.daf.base.PropertyList`` then `value` replaces 318 the existing value. Also the item is added as a live 319 reference, so updating `value` will update this container 324 lsst::pex::exceptions::TypeError 325 If the type of `value` is incompatible with the existing value 328 return _propertyContainerAdd(self, name, value, self.
_typeMenu)
331 """Returns a (possibly nested) dictionary with all properties. 335 for name
in self.names():
336 v = _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
338 if isinstance(v, PropertySet):
339 d[name] = PropertySet.toDict(v)
348 _typeMenu = {bool:
"Bool",
352 DateTime:
"DateTime",
353 PropertySet:
"PropertySet",
354 PropertyList:
"PropertySet",
360 _typeMenu[unicode] =
"String" 365 """Return an item as a scalar or array 367 Return an array if the item has more than one value, 368 otherwise return a scalar. 370 .. deprecated:: 20180-06 371 `get` is superseded by `getArray` or `getScalar` 380 lsst.pex.exceptions.NotFoundError 381 If the item does not exist. 383 warnings.warn(
"Use getArray or getScalar instead", DeprecationWarning, stacklevel=2)
384 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
387 """Return an item as an array 396 lsst.pex.exceptions.NotFoundError 397 If the item does not exist. 399 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.ARRAY)
402 """Return an item as a scalar 404 If the item has more than one value then the last value is returned 413 lsst.pex.exceptions.NotFoundError 414 If the item does not exist. 416 return _propertyContainerGet(self, name, returnStyle=ReturnStyle.SCALAR)
418 def set(self, name, value, comment=None):
419 """Set the value of an item 421 If the item already exists it is silently replaced; the types 428 value : any supported type 429 Value of item; may be a scalar or array 432 if comment
is not None:
434 return _propertyContainerSet(self, name, value, self.
_typeMenu, *args)
436 def add(self, name, value, comment=None):
437 """Append one or more values to a given item, which need not exist 439 If the item exists then the new value(s) are appended; 440 otherwise it is like calling `set` 446 value : any supported type 447 Value of item; may be a scalar or array 451 If `value` is an ``lsst.daf.base.PropertySet`` items are added 452 using dotted names (e.g. if name="a" and value contains 453 an item "b" which is another PropertySet and contains an 454 item "c" which is numeric or string, then the value of "c" 455 is added as "a.b.c", appended to the existing values of 456 "a.b.c" if any (in which case the types must be compatible). 460 lsst::pex::exceptions::TypeError 461 If the type of `value` is incompatible with the existing value 465 if comment
is not None:
467 return _propertyContainerAdd(self, name, value, self.
_typeMenu, *args)
470 orderedNames = self.getOrderedNames()
472 for name
in orderedNames:
473 if self.isArray(name):
474 values = _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO)
476 ret.append((name, v, self.getComment(name)))
478 ret.append((name, _propertyContainerGet(self, name, returnStyle=ReturnStyle.AUTO),
479 self.getComment(name)))
483 """Return an ordered dictionary with all properties in the order that 486 from collections
import OrderedDict
489 for name
in self.getOrderedNames():
490 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)