Package xmlschema_acue ::
Package validators ::
Module builtins
1
2
3
4
5
6
7
8
9
10
11 """
12 This module contains definitions and functions for XSD builtin datatypes.
13
14 Only atomic builtins are created, the list builtins types ('NMTOKENS', 'ENTITIES', 'IDREFS')
15 are created using the XSD 1.0 meta-schema or with and additional base schema for XSD 1.1.
16 """
17 from __future__ import unicode_literals
18
19 import re
20 import base64
21 from decimal import Decimal
22 from math import isinf, isnan
23
24 from elementpath import datatypes
25
26 from xmlschema_acue.compat import PY3, long_type, unicode_type
27 from xmlschema_acue.exceptions import XMLSchemaValueError
28 from xmlschema_acue.qnames import *
29 from xmlschema_acue.etree import etree_element, is_etree_element
30 from xmlschema_acue.validators.exceptions import XMLSchemaValidationError
31 from xmlschema_acue.validators.facets import XSD_10_FACETS_BUILDERS, XSD_11_FACETS_BUILDERS
32 from xmlschema_acue.validators.simple_types import XsdSimpleType, XsdAtomicBuiltin
33
34 HEX_BINARY_PATTERN = re.compile(r'^[0-9a-fA-F]+$')
35 NOT_BASE64_BINARY_PATTERN = re.compile(r'[^0-9a-zA-z+/= \t\n]')
36
37
38
39 STRING_FACETS = (
40 XSD_LENGTH, XSD_MIN_LENGTH, XSD_MAX_LENGTH, XSD_PATTERN,
41 XSD_ENUMERATION, XSD_WHITE_SPACE, XSD_ASSERTION
42 )
43
44 BOOLEAN_FACETS = (XSD_PATTERN, XSD_WHITE_SPACE, XSD_ASSERTION)
45
46 FLOAT_FACETS = (
47 XSD_PATTERN, XSD_ENUMERATION, XSD_WHITE_SPACE, XSD_MAX_INCLUSIVE,
48 XSD_MAX_EXCLUSIVE, XSD_MIN_INCLUSIVE, XSD_MIN_EXCLUSIVE, XSD_ASSERTION
49 )
50
51 DECIMAL_FACETS = (
52 XSD_TOTAL_DIGITS, XSD_FRACTION_DIGITS, XSD_PATTERN, XSD_ENUMERATION,
53 XSD_WHITE_SPACE, XSD_MAX_INCLUSIVE, XSD_MAX_EXCLUSIVE, XSD_MIN_INCLUSIVE,
54 XSD_MIN_EXCLUSIVE, XSD_ASSERTION
55 )
56
57 DATETIME_FACETS = (
58 XSD_PATTERN, XSD_ENUMERATION, XSD_WHITE_SPACE,
59 XSD_MAX_INCLUSIVE, XSD_MAX_EXCLUSIVE, XSD_MIN_INCLUSIVE,
60 XSD_MIN_EXCLUSIVE, XSD_ASSERTION, XSD_EXPLICIT_TIMEZONE
61 )
62
63
64
65
72
73
77
78
82
83
87
88
92
93
97
98
102
103
107
108
112
113
117
118
122
123
127
128
132
133
137
138
142
143
156
157
158
159
161 if s in ('true', '1'):
162 return True
163 elif s in ('false', '0'):
164 return False
165 else:
166 raise XMLSchemaValueError('not a boolean value: %r' % s)
167
168
171
172
173
174
175 PRESERVE_WHITE_SPACE_ELEMENT = etree_element(XSD_WHITE_SPACE, value='preserve')
176 COLLAPSE_WHITE_SPACE_ELEMENT = etree_element(XSD_WHITE_SPACE, value='collapse')
177 REPLACE_WHITE_SPACE_ELEMENT = etree_element(XSD_WHITE_SPACE, value='replace')
178
179
180 XSD_COMMON_BUILTIN_TYPES = (
181
182
183
184
185
186 {
187 'name': XSD_STRING,
188 'python_type': (unicode_type, str),
189 'admitted_facets': STRING_FACETS,
190 'facets': [PRESERVE_WHITE_SPACE_ELEMENT],
191 },
192
193
194 {
195 'name': XSD_DECIMAL,
196 'python_type': (Decimal, str, unicode_type, int, float),
197 'admitted_facets': DECIMAL_FACETS,
198 'facets': [finite_number_validator, COLLAPSE_WHITE_SPACE_ELEMENT],
199 },
200 {
201 'name': XSD_DOUBLE,
202 'python_type': float,
203 'admitted_facets': FLOAT_FACETS,
204 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
205 },
206 {
207 'name': XSD_FLOAT,
208 'python_type': float,
209 'admitted_facets': FLOAT_FACETS,
210 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
211 },
212
213
214 {
215 'name': XSD_GDAY,
216 'python_type': (unicode_type, str, datatypes.GregorianDay),
217 'admitted_facets': DATETIME_FACETS,
218 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
219 'to_python': datatypes.GregorianDay.fromstring,
220 },
221 {
222 'name': XSD_GMONTH,
223 'python_type': (unicode_type, str, datatypes.GregorianMonth),
224 'admitted_facets': DATETIME_FACETS,
225 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
226 'to_python': datatypes.GregorianMonth.fromstring,
227 },
228 {
229 'name': XSD_GMONTH_DAY,
230 'python_type': (unicode_type, str, datatypes.GregorianMonthDay),
231 'admitted_facets': DATETIME_FACETS,
232 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
233 'to_python': datatypes.GregorianMonthDay.fromstring,
234 },
235 {
236 'name': XSD_TIME,
237 'python_type': (unicode_type, str, datatypes.Time),
238 'admitted_facets': DATETIME_FACETS,
239 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
240 'to_python': datatypes.Time.fromstring,
241 },
242 {
243 'name': XSD_DURATION,
244 'python_type': (unicode_type, str, datatypes.Duration),
245 'admitted_facets': FLOAT_FACETS,
246 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
247 'to_python': datatypes.Duration.fromstring,
248 },
249
250
251 {
252 'name': XSD_QNAME,
253 'python_type': (unicode_type, str),
254 'admitted_facets': STRING_FACETS,
255 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT, qname_validator],
256 },
257 {
258 'name': XSD_NOTATION_TYPE,
259 'python_type': (unicode_type, str),
260 'admitted_facets': STRING_FACETS,
261 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
262 },
263 {
264 'name': XSD_ANY_URI,
265 'python_type': (unicode_type, str),
266 'admitted_facets': STRING_FACETS,
267 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
268 },
269 {
270 'name': XSD_BOOLEAN,
271 'python_type': bool,
272 'admitted_facets': BOOLEAN_FACETS,
273 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
274 'to_python': boolean_to_python,
275 'from_python': python_to_boolean,
276 },
277 {
278 'name': XSD_BASE64_BINARY,
279 'python_type': (unicode_type, str),
280 'admitted_facets': STRING_FACETS,
281 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT, base64_binary_validator],
282 },
283 {
284 'name': XSD_HEX_BINARY,
285 'python_type': (unicode_type, str),
286 'admitted_facets': STRING_FACETS,
287 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT, hex_binary_validator],
288 },
289
290
291
292
293
294
295 {
296 'name': XSD_NORMALIZED_STRING,
297 'python_type': (unicode_type, str),
298 'base_type': XSD_STRING,
299 'facets': [REPLACE_WHITE_SPACE_ELEMENT],
300 },
301 {
302 'name': XSD_TOKEN,
303 'python_type': (unicode_type, str),
304 'base_type': XSD_NORMALIZED_STRING,
305 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
306 },
307 {
308 'name': XSD_LANGUAGE,
309 'python_type': (unicode_type, str),
310 'base_type': XSD_TOKEN,
311 'facets': [
312 etree_element(XSD_PATTERN, value=r"([a-zA-Z]{2}|[iI]-[a-zA-Z]+|[xX]-[a-zA-Z]{1,8})(-[a-zA-Z]{1,8})*")
313 ]
314 },
315 {
316 'name': XSD_NAME,
317 'python_type': (unicode_type, str),
318 'base_type': XSD_TOKEN,
319 'facets': [etree_element(XSD_PATTERN, value=r"\i\c*")]
320 },
321 {
322 'name': XSD_NCNAME,
323 'python_type': (unicode_type, str),
324 'base_type': XSD_NAME,
325 'facets': [etree_element(XSD_PATTERN, value=r"[\i-[:]][\c-[:]]*")]
326 },
327 {
328 'name': XSD_ID,
329 'python_type': (unicode_type, str),
330 'base_type': XSD_NCNAME
331 },
332 {
333 'name': XSD_IDREF,
334 'python_type': (unicode_type, str),
335 'base_type': XSD_NCNAME
336 },
337 {
338 'name': XSD_ENTITY,
339 'python_type': (unicode_type, str),
340 'base_type': XSD_NCNAME
341 },
342 {
343 'name': XSD_NMTOKEN,
344 'python_type': (unicode_type, str),
345 'base_type': XSD_TOKEN,
346 'facets': [etree_element(XSD_PATTERN, value=r"\c+")]
347 },
348
349
350 {
351 'name': XSD_INTEGER,
352 'python_type': int if PY3 else (long_type, int),
353 'base_type': XSD_DECIMAL
354 },
355 {
356 'name': XSD_LONG,
357 'python_type': int if PY3 else (long_type, int),
358 'base_type': XSD_INTEGER,
359 'facets': [long_validator,
360 etree_element(XSD_MIN_INCLUSIVE, value='-9223372036854775808'),
361 etree_element(XSD_MAX_INCLUSIVE, value='9223372036854775807')]
362 },
363 {
364 'name': XSD_INT,
365 'python_type': int,
366 'base_type': XSD_LONG,
367 'facets': [int_validator,
368 etree_element(XSD_MIN_INCLUSIVE, value='-2147483648'),
369 etree_element(XSD_MAX_INCLUSIVE, value='2147483647')]
370 },
371 {
372 'name': XSD_SHORT,
373 'python_type': int,
374 'base_type': XSD_INT,
375 'facets': [short_validator,
376 etree_element(XSD_MIN_INCLUSIVE, value='-32768'),
377 etree_element(XSD_MAX_INCLUSIVE, value='32767')]
378 },
379 {
380 'name': XSD_BYTE,
381 'python_type': int,
382 'base_type': XSD_SHORT,
383 'facets': [byte_validator,
384 etree_element(XSD_MIN_INCLUSIVE, value='-128'),
385 etree_element(XSD_MAX_INCLUSIVE, value='127')]
386 },
387 {
388 'name': XSD_NON_NEGATIVE_INTEGER,
389 'python_type': int if PY3 else (long_type, int),
390 'base_type': XSD_INTEGER,
391 'facets': [non_negative_int_validator, etree_element(XSD_MIN_INCLUSIVE, value='0')]
392 },
393 {
394 'name': XSD_POSITIVE_INTEGER,
395 'python_type': int if PY3 else (long_type, int),
396 'base_type': XSD_NON_NEGATIVE_INTEGER,
397 'facets': [positive_int_validator, etree_element(XSD_MIN_INCLUSIVE, value='1')]
398 },
399 {
400 'name': XSD_UNSIGNED_LONG,
401 'python_type': int if PY3 else (long_type, int),
402 'base_type': XSD_NON_NEGATIVE_INTEGER,
403 'facets': [unsigned_long_validator, etree_element(XSD_MAX_INCLUSIVE, value='18446744073709551615')]
404 },
405 {
406 'name': XSD_UNSIGNED_INT,
407 'python_type': int,
408 'base_type': XSD_UNSIGNED_LONG,
409 'facets': [unsigned_int_validator, etree_element(XSD_MAX_INCLUSIVE, value='4294967295')]
410 },
411 {
412 'name': XSD_UNSIGNED_SHORT,
413 'python_type': int,
414 'base_type': XSD_UNSIGNED_INT,
415 'facets': [unsigned_short_validator, etree_element(XSD_MAX_INCLUSIVE, value='65535')]
416 },
417 {
418 'name': XSD_UNSIGNED_BYTE,
419 'python_type': int,
420 'base_type': XSD_UNSIGNED_SHORT,
421 'facets': [unsigned_byte_validator, etree_element(XSD_MAX_INCLUSIVE, value='255')]
422 },
423 {
424 'name': XSD_NON_POSITIVE_INTEGER,
425 'python_type': (long_type, int),
426 'base_type': XSD_INTEGER,
427 'facets': [non_positive_int_validator, etree_element(XSD_MAX_INCLUSIVE, value='0')]
428 },
429 {
430 'name': XSD_NEGATIVE_INTEGER,
431 'python_type': (long_type, int),
432 'base_type': XSD_NON_POSITIVE_INTEGER,
433 'facets': [negative_int_validator, etree_element(XSD_MAX_INCLUSIVE, value='-1')]
434 },
435 )
436
437 XSD_10_BUILTIN_TYPES = XSD_COMMON_BUILTIN_TYPES + (
438
439 {
440 'name': XSD_DATETIME,
441 'python_type': (unicode_type, str, datatypes.DateTime10),
442 'admitted_facets': DATETIME_FACETS,
443 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
444 'to_python': datatypes.DateTime10.fromstring,
445 },
446 {
447 'name': XSD_DATE,
448 'python_type': (unicode_type, str, datatypes.Date10),
449 'admitted_facets': DATETIME_FACETS,
450 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
451 'to_python': datatypes.Date10.fromstring,
452 },
453 {
454 'name': XSD_GYEAR,
455 'python_type': (unicode_type, str, datatypes.GregorianYear10),
456 'admitted_facets': DATETIME_FACETS,
457 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
458 'to_python': datatypes.GregorianYear10.fromstring,
459 },
460 {
461 'name': XSD_GYEAR_MONTH,
462 'python_type': (unicode_type, str, datatypes.GregorianYearMonth10),
463 'admitted_facets': DATETIME_FACETS,
464 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
465 'to_python': datatypes.GregorianYearMonth10.fromstring,
466 },
467 )
468
469 XSD_11_BUILTIN_TYPES = XSD_COMMON_BUILTIN_TYPES + (
470
471 {
472 'name': XSD_DATETIME,
473 'python_type': (unicode_type, str, datatypes.DateTime),
474 'admitted_facets': DATETIME_FACETS,
475 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
476 'to_python': datatypes.DateTime.fromstring,
477 },
478 {
479 'name': XSD_DATE,
480 'python_type': (unicode_type, str, datatypes.Date),
481 'admitted_facets': DATETIME_FACETS,
482 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
483 'to_python': datatypes.Date.fromstring,
484 },
485 {
486 'name': XSD_GYEAR,
487 'python_type': (unicode_type, str, datatypes.GregorianYear),
488 'admitted_facets': DATETIME_FACETS,
489 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
490 'to_python': datatypes.GregorianYear.fromstring,
491 },
492 {
493 'name': XSD_GYEAR_MONTH,
494 'python_type': (unicode_type, str, datatypes.GregorianYearMonth),
495 'admitted_facets': DATETIME_FACETS,
496 'facets': [COLLAPSE_WHITE_SPACE_ELEMENT],
497 'to_python': datatypes.GregorianYearMonth.fromstring,
498 },
499
500 {
501 'name': XSD_DATE_TIME_STAMP,
502 'python_type': (unicode_type, str),
503 'base_type': XSD_DATETIME,
504 'to_python': datatypes.DateTime.fromstring,
505 'facets': [etree_element(XSD_EXPLICIT_TIMEZONE, value='required')],
506 },
507 {
508 'name': XSD_DAY_TIME_DURATION,
509 'python_type': (unicode_type, str),
510 'base_type': XSD_DURATION,
511 'to_python': datatypes.DayTimeDuration.fromstring,
512 },
513 {
514 'name': XSD_YEAR_MONTH_DURATION,
515 'python_type': (unicode_type, str),
516 'base_type': XSD_DURATION,
517 'to_python': datatypes.YearMonthDuration.fromstring,
518 },
519 )
520
521
523 """
524 Builds the dictionary for XML Schema built-in types mapping.
525 """
526 atomic_builtin_class = atomic_builtin_class or XsdAtomicBuiltin
527 if meta_schema.XSD_VERSION == '1.1':
528 builtin_types = XSD_11_BUILTIN_TYPES
529 facets_map = XSD_11_FACETS_BUILDERS
530 else:
531 builtin_types = XSD_10_BUILTIN_TYPES
532 facets_map = XSD_10_FACETS_BUILDERS
533
534
535
536
537
538
539 any_type = meta_schema.BUILDERS.complex_type_class(
540 elem=etree_element(XSD_COMPLEX_TYPE, name=XSD_ANY_TYPE),
541 schema=meta_schema,
542 parent=None,
543 mixed=True
544 )
545 any_type.content_type = meta_schema.create_any_content_group(any_type)
546 any_type.attributes = meta_schema.create_any_attribute_group(any_type)
547 xsd_types[XSD_ANY_TYPE] = any_type
548
549
550
551 xsd_types[XSD_ANY_SIMPLE_TYPE] = XsdSimpleType(
552 elem=etree_element(XSD_SIMPLE_TYPE, name=XSD_ANY_SIMPLE_TYPE),
553 schema=meta_schema,
554 parent=None,
555 name=XSD_ANY_SIMPLE_TYPE
556 )
557
558
559
560 xsd_types[XSD_ANY_ATOMIC_TYPE] = meta_schema.BUILDERS.restriction_class(
561 elem=etree_element(XSD_SIMPLE_TYPE, name=XSD_ANY_ATOMIC_TYPE),
562 schema=meta_schema,
563 parent=None,
564 name=XSD_ANY_ATOMIC_TYPE,
565 base_type=xsd_types[XSD_ANY_SIMPLE_TYPE]
566 )
567
568 for item in builtin_types:
569 item = item.copy()
570 name = item['name']
571 try:
572 elem, schema = xsd_types[name]
573 except KeyError:
574
575
576 elem = etree_element(XSD_SIMPLE_TYPE, name=name, id=name)
577 else:
578 if schema is not meta_schema:
579 raise XMLSchemaValueError("loaded entry schema doesn't match meta_schema!")
580
581 if 'base_type' in item:
582 base_type = item['base_type'] = xsd_types[item['base_type']]
583 else:
584 base_type = None
585
586 facets = item.pop('facets', None)
587 builtin_type = atomic_builtin_class(elem, meta_schema, **item)
588 if isinstance(facets, (list, tuple)):
589 built_facets = builtin_type.facets
590 for e in facets:
591 if is_etree_element(e):
592 cls = facets_map[e.tag]
593 built_facets[e.tag] = cls(e, meta_schema, builtin_type, base_type)
594 elif callable(e):
595 if None in facets:
596 raise XMLSchemaValueError("Almost one callable for facet group!!")
597 built_facets[None] = e
598 else:
599 raise XMLSchemaValueError("Wrong type for item %r" % e)
600 builtin_type.facets = built_facets
601
602 xsd_types[name] = builtin_type
603