24 from __future__
import absolute_import, division, print_function
26 __all__ = [
"getstate",
"setstate"]
28 from past.builtins
import long
31 from lsst.utils
import continueClass
33 from .propertySet
import PropertySet
34 from .propertyList
import PropertyList
36 import lsst.pex.exceptions
37 from ..dateTime
import DateTime
40 def _propertyContainerElementTypeName(container, name):
41 """Return name of the type of a particular element"""
42 t = container.typeOf(name)
43 for checkType
in (
"Bool",
"Short",
"Int",
"Long",
"LongLong",
"Float",
"Double",
"String",
"DateTime"):
44 if t == getattr(container,
"TYPE_" + checkType):
49 def _propertyContainerGet(container, name, asArray=False):
50 """Extract a single Python value of unknown type"""
51 if not container.exists(name):
52 raise lsst.pex.exceptions.NotFoundError(name +
" not found")
54 elemType = _propertyContainerElementTypeName(container, name)
56 value = getattr(container,
"getArray" + elemType)(name)
57 return value[0]
if len(value) == 1
and not asArray
else value
60 return container.getAsPropertyListPtr(name)
63 if container.typeOf(name) == container.TYPE_PropertySet:
64 return container.getAsPropertySetPtr(name)
66 return container.getAsPersistablePtr(name)
69 raise lsst.pex.exceptions.TypeError(
'Unknown PropertySet value type for ' + name)
72 def _guessIntegerType(container, name, value):
73 """Given an existing container and name, determine the type
74 that should be used for the supplied value. The supplied value
75 is assumed to be a scalar.
77 On Python 3 all ints are LongLong but we need to be able to store them
78 in Int containers if that is what is being used (testing for truncation).
79 Int is assumed to mean 32bit integer (2147483647 to -2147483648).
81 If there is no pre-existing value we have to decide what to do. For now
82 we pick Int if the value is less than maxsize.
84 Returns None if the value supplied is a bool or not an integral value.
92 if isinstance(value, bool):
95 if isinstance(value, numbers.Integral):
97 containerType = _propertyContainerElementTypeName(container, name)
98 except lsst.pex.exceptions.NotFoundError:
101 if value <= maxInt
and value >= minInt:
106 if containerType ==
"Int":
112 elif containerType ==
"LongLong":
117 def _propertyContainerSet(container, name, value, typeMenu, *args):
118 """Set a single Python value of unknown type"""
119 if hasattr(value,
"__iter__")
and not isinstance(value, str):
125 setType = _guessIntegerType(container, name, exemplar)
127 if setType
is not None or t
in typeMenu:
129 setType = typeMenu[t]
130 return getattr(container,
"set" + setType)(name, value, *args)
132 for checkType
in typeMenu:
133 if isinstance(exemplar, checkType):
134 return getattr(container,
"set" + typeMenu[checkType])(name, value, *args)
135 raise lsst.pex.exceptions.TypeError(
"Unknown value type for %s: %s" % (name, t))
138 def _propertyContainerAdd(container, name, value, typeMenu, *args):
139 """Add a single Python value of unknown type"""
140 if hasattr(value,
"__iter__"):
146 addType = _guessIntegerType(container, name, exemplar)
148 if addType
is not None or t
in typeMenu:
150 addType = typeMenu[t]
151 return getattr(container,
"add" + addType)(name, value, *args)
153 for checkType
in typeMenu:
154 if isinstance(exemplar, checkType):
155 return getattr(container,
"add" + typeMenu[checkType])(name, value, *args)
156 raise lsst.pex.exceptions.TypeError(
"Unknown value type for %s: %s" % (name, t))
160 return [(name, _propertyContainerElementTypeName(self, name), self.get(name),
161 self.getComment(name))
for name
in self.getOrderedNames()]
165 for name, elemType, value, comment
in state:
166 getattr(self,
"set" + elemType)(name, value, comment)
172 _typeMenu = {bool:
"Bool",
177 DateTime:
"DateTime",
178 PropertySet:
"PropertySet",
179 PropertyList:
"PropertySet",
185 _typeMenu[unicode] =
"String"
189 def get(self, name, asArray=False):
190 return _propertyContainerGet(self, name, asArray)
192 def set(self, name, value):
193 return _propertyContainerSet(self, name, value, self.
_typeMenu)
195 def add(self, name, value):
196 return _propertyContainerAdd(self, name, value, self.
_typeMenu)
199 """Returns a (possibly nested) dictionary with all properties.
203 for name
in self.names():
206 if isinstance(v, PropertySet):
207 d[name] = PropertySet.toDict(v)
216 _typeMenu = {bool:
"Bool",
221 DateTime:
"DateTime",
222 PropertySet:
"PropertySet",
223 PropertyList:
"PropertySet",
229 _typeMenu[unicode] =
"String"
233 def get(self, name, asArray=False):
234 return _propertyContainerGet(self, name, asArray)
236 def set(self, name, value, comment=None):
238 if comment
is not None:
240 return _propertyContainerSet(self, name, value, self.
_typeMenu, *args)
242 def add(self, name, value, comment=None):
244 if comment
is not None:
246 return _propertyContainerAdd(self, name, value, self.
_typeMenu, *args)
249 orderedNames = self.getOrderedNames()
251 for name
in orderedNames:
252 if self.isArray(name):
253 values = self.
get(name)
255 ret.append((name, v, self.getComment(name)))
257 ret.append((name, self.
get(name), self.getComment(name)))
261 """Return an ordered dictionary with all properties in the order that
264 from collections
import OrderedDict
267 for name
in self.getOrderedNames():
268 d[name] = self.
get(name)