1 """
2 Serialisation of python values to VOTable PARAM values.
3
4 This has two aspects:
5
6 - Guessing proper VOTable type descriptors for python values
7 (use guessParamAttrsForValue)
8 - Serialising the python values to strings suitable for the PARAM.
9 (use serializeToParam)
10 """
11
12
13
14
15
16
17
18 import datetime
19
20 from gavo import utils
21 from gavo.utils import pgsphere
22 from gavo.utils import serializers
23 from gavo.votable import coding
24 from gavo.votable import common
25 from gavo.votable import enc_tabledata
26 from gavo.votable import dec_tabledata
27 from gavo.votable.model import VOTable as V
28
29
30 _SEQUENCE_TYPES = (tuple, list)
31 _ATOMIC_TYPES = [
32 (long, {"datatype": "long"}),
33 (int, {"datatype": "int"}),
34 (str, {"datatype": "char", "arraysize": "*"}),
35 (basestring, {"datatype": "unicodeChar", "arraysize": "*"}),
36 (float, {"datatype": "double"}),
37 (type(None), {"datatype": "double"}),
38 (complex, {"datatype": "doubleComplex"}),
39 (datetime.datetime, {"datatype": "char",
40 "arraysize": "20",
41 "xtype": "timestamp"}),
42 (datetime.date, {"datatype": "char",
43 "arraysize": "20",
44 "xtype": "dachs:DATE"}),
45 (pgsphere.SPoint, {"datatype": "double precision",
46 "arraysize": "2",
47 "xtype": "point"}),
48 (pgsphere.SCircle, {"datatype": "double precision",
49 "arraysize": "3",
50 "xtype": "circle"}),
51 (pgsphere.SPoly, {"datatype": "double precision",
52 "arraysize": "*",
53 "xtype": "polygon"}),]
57 """makes an arraysize attribute for a value with attrs.
58
59 This will in particular check that any existing arraysize in
60 attrs does not end with a star (as variable length is only allowed
61 in the slowest coordinate).
62
63 attrs is changed in place.
64 """
65 if "arraysize" in attrs:
66 if attrs["arraysize"].endswith("*"):
67 raise ValueError("Arrays of variable-length arrays are not allowed.")
68 attrs["arraysize"] = "%sx%s"%(attrs["arraysize"], arraysize)
69 else:
70 attrs["arraysize"] = arraysize
71
74 """helps guessParamAttrsForValue when the value is a sequence.
75 """
76 arraysize = str(len(pythonVal))
77 if len(pythonVal)==0:
78 return {
79 "datatype": "char",
80 "arraysize": "0"}
81
82 elementVal = pythonVal[0]
83
84 if isinstance(elementVal, basestring):
85
86 attrs = {
87 "arraysize": "%sx%s"%(
88 max(len(s) for s in pythonVal), arraysize),
89 "datatype": "char"}
90
91 elif isinstance(elementVal, _SEQUENCE_TYPES):
92 attrs = _guessParamAttrsForSequence(elementVal)
93 _combineArraysize(arraysize, attrs)
94
95 else:
96 attrs = _guessParamAttrsForAtom(elementVal)
97 _combineArraysize(arraysize, attrs)
98
99 return attrs
100
103 """helps guessParamAttrsForValue when the value is atomic.
104
105 (where "atomic" includes string, and other things that actually
106 have non-1 arraysize).
107 """
108 for type, attrs in _ATOMIC_TYPES:
109 if isinstance(pythonVal, type):
110 return attrs.copy()
111
112 raise utils.NotFoundError(repr(pythonVal),
113 "VOTable type code for", "paramval.py predefined types")
114
117 """returns a dict of proposed attributes for a PARAM to keep pythonVal.
118
119 There is, of course, quite a bit of heuristics involved. For instance,
120 we assume sequences are homogeneous.
121 """
122 if isinstance(pythonVal, _SEQUENCE_TYPES):
123 return _guessParamAttrsForSequence(pythonVal)
124
125 else:
126 return _guessParamAttrsForAtom(pythonVal)
127
137
159
162 """A stand-in for serializers.AnnotatedColumn.
163
164 We don't want to use the full thing as it's too fat here, and
165 getVOTSerializer doesn't have the original param anyway (as
166 it shouldn't, as that would break memoization).
167 """
168
172
173 - def __init__(self, datatype, arraysize, xtype):
174 dict.__init__(self, {
175 "nullvalue": "",
176 "name": "anonymous",
177 "dbtype": None,
178 "displayHint": {},
179 "note": None,
180 "ucd": None,
181 "utype": None,
182 "unit": None,
183 "description": None,
184 "id": None,
185 "datatype": datatype,
186 "arraysize": arraysize,
187 "xtype": xtype})
188
209
212 """changes the VOTable PARAM param such that val is represented.
213
214 This may involve adding a null value.
215 """
216 if val is None:
217 _serializeNULL(param)
218 else:
219 param.value = getVOTSerializer(
220 param.datatype, param.arraysize, param.xtype)(val)
221
240