@@ -200,8 +200,18 @@ def clear_type(self):
200
200
pass
201
201
202
202
def set_text (self , value , base64encode = False ):
203
+ def _wrong_type_value (xs_type , value ):
204
+ msg = _str ('Type and value do not match: {xs_type}:{type}:{value}' )
205
+ msg = msg .format (xs_type = xs_type , type = type (value ), value = value )
206
+ raise ValueError (msg )
207
+
208
+ # only work with six.string_types
209
+ _str = unicode if six .PY2 else str
210
+ if isinstance (value , six .binary_type ):
211
+ value = value .decode ()
212
+
203
213
xs_type_from_type = {
204
- str : 'xs:string' ,
214
+ _str : 'xs:string' ,
205
215
int : 'xs:integer' ,
206
216
float : 'xs:float' ,
207
217
bool : 'xs:boolean' ,
@@ -210,60 +220,60 @@ def set_text(self, value, base64encode=False):
210
220
211
221
xs_types_map = {
212
222
'xs:string' : {
213
- 'type' : str ,
214
- 'typed_constructor' : str ,
215
- 'text_constructor' : str ,
223
+ 'type' : _str ,
224
+ 'typed_constructor' : _str ,
225
+ 'text_constructor' : _str ,
216
226
},
217
227
'xs:integer' : {
218
228
'type' : int ,
219
229
'typed_constructor' : int ,
220
- 'text_constructor' : str ,
230
+ 'text_constructor' : _str ,
221
231
},
222
232
'xs:short' : {
223
233
'type' : int ,
224
234
'typed_constructor' : int ,
225
- 'text_constructor' : str ,
235
+ 'text_constructor' : _str ,
226
236
},
227
237
'xs:int' : {
228
238
'type' : int ,
229
239
'typed_constructor' : int ,
230
- 'text_constructor' : str ,
240
+ 'text_constructor' : _str ,
231
241
},
232
242
'xs:long' : {
233
243
'type' : int ,
234
244
'typed_constructor' : int ,
235
- 'text_constructor' : str ,
245
+ 'text_constructor' : _str ,
236
246
},
237
247
'xs:float' : {
238
248
'type' : float ,
239
249
'typed_constructor' : float ,
240
- 'text_constructor' : str ,
250
+ 'text_constructor' : _str ,
241
251
},
242
252
'xs:double' : {
243
253
'type' : float ,
244
254
'typed_constructor' : float ,
245
- 'text_constructor' : str ,
255
+ 'text_constructor' : _str ,
246
256
},
247
257
'xs:boolean' : {
248
258
'type' : bool ,
249
- 'typed_constructor' : lambda x :
250
- True if str ( x ). lower () == 'true'
251
- else False if str ( x ). lower () == 'false'
252
- else None ,
253
- 'text_constructor' : lambda x : str (x ).lower (),
259
+ 'typed_constructor' : lambda x : {
260
+ 'true' : True ,
261
+ 'false' : False ,
262
+ }[ _str ( x ). lower ()] ,
263
+ 'text_constructor' : lambda x : _str (x ).lower (),
254
264
},
255
265
'xs:base64Binary' : {
256
- 'type' : str ,
257
- 'typed_constructor' : str ,
266
+ 'type' : _str ,
267
+ 'typed_constructor' : _str ,
258
268
'text_constructor' : lambda x :
259
269
_b64_encode_fn (x .encode ())
260
270
if base64encode
261
271
else x ,
262
272
},
263
273
'xs:anyType' : {
264
274
'type' : type (value ),
265
- 'typed_constructor' : lambda x : value ,
266
- 'text_constructor' : lambda x : value ,
275
+ 'typed_constructor' : lambda x : x ,
276
+ 'text_constructor' : lambda x : x ,
267
277
},
268
278
'' : {
269
279
'type' : type (None ),
@@ -272,9 +282,6 @@ def set_text(self, value, base64encode=False):
272
282
},
273
283
}
274
284
275
- if isinstance (value , six .binary_type ):
276
- value = value .decode ()
277
-
278
285
xs_type = \
279
286
'xs:base64Binary' \
280
287
if base64encode \
@@ -285,11 +292,16 @@ def set_text(self, value, base64encode=False):
285
292
to_typed = xs_type_map .get ('typed_constructor' , str )
286
293
to_text = xs_type_map .get ('text_constructor' , str )
287
294
288
- value = to_typed (value )
295
+ # cast to correct type before type-checking
296
+ if type (value ) is _str and valid_type is not _str :
297
+ try :
298
+ value = to_typed (value )
299
+ except (TypeError , ValueError , KeyError ) as e :
300
+ # the cast failed
301
+ _wrong_type_value (xs_type = xs_type , value = value )
302
+
289
303
if type (value ) is not valid_type :
290
- msg_tpl = 'Type and value do not match: {type}:{value}'
291
- msg = msg_tpl .format (type = xs_type , value = value )
292
- raise ValueError (msg )
304
+ _wrong_type_value (xs_type = xs_type , value = value )
293
305
294
306
text = to_text (value )
295
307
self .set_type (xs_type )
0 commit comments