1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """Classes supporting U{XMLSchema Part 2: Datatypes<http://www.w3.org/TR/xmlschema-2/>}.
17
18 Each L{simple type definition<pyxb.xmlschema.structures.SimpleTypeDefinition>} component
19 instance is paired with at most one L{basis.simpleTypeDefinition}
20 class, which is a subclass of a Python type augmented with facets and
21 other constraining information. This file contains the definitions of
22 these types.
23
24 We want the simple datatypes to be efficient Python values, but to
25 also hold specific constraints that don't apply to the Python types.
26 To do this, we subclass each PST. Primitive PSTs inherit from the
27 Python type that represents them, and from a
28 pyxb.binding.basis.simpleTypeDefinition class which adds in the
29 constraint infrastructure. Derived PSTs inherit from the parent PST.
30
31 There is an exception to this when the Python type best suited for a
32 derived SimpleTypeDefinition differs from the type associated with its
33 parent STD: for example, L{xsd:integer<integer>} has a value range
34 that requires it be represented by a Python C{long}, but
35 L{xsd:int<int>} allows representation by a Python C{int}. In this
36 case, the derived PST class is structured like a primitive type, but
37 the PST associated with the STD superclass is recorded in a class
38 variable C{_XsdBaseType}.
39
40 Note the strict terminology: "datatype" refers to a class which is a
41 subclass of a Python type, while "type definition" refers to an
42 instance of either SimpleTypeDefinition or ComplexTypeDefinition.
43
44 """
45
46 import logging
47 import re
48 import binascii
49 import base64
50 import decimal as python_decimal
51 from pyxb.exceptions_ import *
52 import pyxb.namespace
53 import pyxb.utils.unicode
54 from pyxb.utils import six
55 from . import basis
56
57 _log = logging.getLogger(__name__)
58
59 _PrimitiveDatatypes = []
60 _DerivedDatatypes = []
61 _ListDatatypes = []
62
63
64
65
66 -class anySimpleType (basis.simpleTypeDefinition, six.text_type):
74
75
76
77 -class string (basis.simpleTypeDefinition, six.text_type):
90
91 _PrimitiveDatatypes.append(string)
92
93
94
95 @six.unicode_convertible
96 -class boolean (basis.simpleTypeDefinition, six.int_type):
97 """XMLSchema datatype U{boolean<http://www.w3.org/TR/xmlschema-2/#boolean>}."""
98 _XsdBaseType = anySimpleType
99 _ExpandedName = pyxb.namespace.XMLSchema.createExpandedName('boolean')
100
101 @classmethod
103 if value:
104 return 'true'
105 return 'false'
106
108 if self:
109 return six.u('true')
110 return six.u('false')
111
113 args = cls._ConvertArguments(args, kw)
114 if 0 < len(args):
115 value = args[0]
116 args = args[1:]
117 if value in (1, 0, '1', '0', 'true', 'false'):
118 if value in (1, '1', 'true'):
119 iv = True
120 else:
121 iv = False
122 return super(boolean, cls).__new__(cls, iv, *args, **kw)
123 raise SimpleTypeValueError(cls, value)
124 return super(boolean, cls).__new__(cls, *args, **kw)
125
126 _PrimitiveDatatypes.append(boolean)
127
128 -class decimal (basis.simpleTypeDefinition, python_decimal.Decimal, basis._RepresentAsXsdLiteral_mixin):
129 """XMLSchema datatype U{decimal<http://www.w3.org/TR/xmlschema-2/#decimal>}.
130
131 This class uses Python's L{decimal.Decimal} class to support (by
132 default) 28 significant digits. Only normal and zero values are
133 valid; this means C{NaN} and C{Infinity} may be created during
134 calculations, but cannot be expressed in XML documents.
135 """
136 _XsdBaseType = anySimpleType
137 _ExpandedName = pyxb.namespace.XMLSchema.createExpandedName('decimal')
138
150
151 @classmethod
156
157 @classmethod
159 (sign, digits, exponent) = value.normalize().as_tuple()
160 if (0 < len(digits)) and (0 == digits[0]):
161 digits = ()
162 rchars = []
163 if sign:
164 rchars.append('-')
165 digits_before = len(digits) + exponent
166 if 0 < digits_before:
167 rchars.extend(map(str, digits[:digits_before]))
168 digits = digits[digits_before:]
169 if (0 == len(digits)) and (0 < exponent):
170 rchars.extend(['0'] * exponent)
171 exponent = 0
172 else:
173 rchars.append('0')
174 rchars.append('.')
175 digits_after = -exponent
176 assert(0 <= digits_after)
177 if 0 < digits_after:
178 rchars.extend(['0'] * (digits_after - len(digits)))
179 rchars.extend(map(str, digits))
180 else:
181 rchars.append('0')
182 return six.u('').join(rchars)
183
184 _PrimitiveDatatypes.append(decimal)
185
186 -class float (basis.simpleTypeDefinition, six.float_type):
194
195 _PrimitiveDatatypes.append(float)
196
197 -class double (basis.simpleTypeDefinition, six.float_type):
205
206 _PrimitiveDatatypes.append(double)
207
208 import datetime
209
210 -class duration (basis.simpleTypeDefinition, datetime.timedelta, basis._RepresentAsXsdLiteral_mixin):
211 """XMLSchema datatype U{duration<http://www.w3.org/TR/xmlschema-2/#duration>}.
212
213 This class uses the Python C{datetime.timedelta} class as its
214 underlying representation. This works fine as long as no months
215 or years are involved, and no negative durations are involved.
216 Because the XML Schema value space is so much larger, it is kept
217 distinct from the Python value space, which reduces to integral
218 days, seconds, and microseconds.
219
220 In other words, the implementation of this type is a little
221 shakey.
222
223 """
224
225 _XsdBaseType = anySimpleType
226 _ExpandedName = pyxb.namespace.XMLSchema.createExpandedName('duration')
227
228 __Lexical_re = re.compile('^(?P<neg>-?)P((?P<years>\d+)Y)?((?P<months>\d+)M)?((?P<days>\d+)D)?(?P<Time>T((?P<hours>\d+)H)?((?P<minutes>\d+)M)?(((?P<seconds>\d+)(?P<fracsec>\.\d+)?)S)?)?$')
229
230
231 __XSDFields = ( 'years', 'months', 'days', 'hours', 'minutes', 'seconds' )
232 __PythonFields = ( 'days', 'seconds', 'microseconds', 'minutes', 'hours' )
233
236 __negativeDuration = None
237
240 __durationData = None
241
243 args = cls._ConvertArguments(args, kw)
244 have_kw_update = False
245 if not kw.get('_nil'):
246 if 0 == len(args):
247 raise SimpleTypeValueError(cls, args)
248 text = args[0]
249 if kw.get('_nil'):
250 data = dict(zip(cls.__PythonFields, len(cls.__PythonFields) * [0,]))
251 negative_duration = False
252 elif isinstance(text, six.string_types):
253 match = cls.__Lexical_re.match(text)
254 if match is None:
255 raise SimpleTypeValueError(cls, text)
256 match_map = match.groupdict()
257 if 'T' == match_map.get('Time'):
258
259 raise SimpleTypeValueError(cls, text)
260
261 negative_duration = ('-' == match_map.get('neg'))
262
263 fractional_seconds = 0.0
264 if match_map.get('fracsec') is not None:
265 fractional_seconds = six.float_type('0%s' % (match_map['fracsec'],))
266 usec = six.int_type(1000000 * fractional_seconds)
267 if negative_duration:
268 kw['microseconds'] = - usec
269 else:
270 kw['microseconds'] = usec
271 else:
272
273 kw.pop('microsecond', None)
274
275 data = { }
276 for fn in cls.__XSDFields:
277 v = match_map.get(fn, 0)
278 if v is None:
279 v = 0
280 data[fn] = six.int_type(v)
281 if fn in cls.__PythonFields:
282 if negative_duration:
283 kw[fn] = - data[fn]
284 else:
285 kw[fn] = data[fn]
286 data['seconds'] += fractional_seconds
287 have_kw_update = True
288 elif isinstance(text, cls):
289 data = text.durationData().copy()
290 negative_duration = text.negativeDuration()
291 elif isinstance(text, datetime.timedelta):
292 data = { 'days' : text.days,
293 'seconds' : text.seconds + (text.microseconds / 1000000.0) }
294 negative_duration = (0 > data['days'])
295 if negative_duration:
296 if 0.0 == data['seconds']:
297 data['days'] = - data['days']
298 else:
299 data['days'] = 1 - data['days']
300 data['seconds'] = 24 * 60 * 60.0 - data['seconds']
301 data['minutes'] = 0
302 data['hours'] = 0
303 elif isinstance(text, six.integer_types) and (1 < len(args)):
304
305 data = dict(zip(cls.__PythonFields[:len(args)], args))
306 negative_duration = False
307 else:
308 raise SimpleTypeValueError(cls, text)
309 if not have_kw_update:
310 rem_time = data.pop('seconds', 0)
311 if (0 != (rem_time % 1)):
312 data['microseconds'] = data.pop('microseconds', 0) + six.int_type(1000000 * (rem_time % 1))
313 rem_time = rem_time // 1
314 data['seconds'] = rem_time % 60
315 rem_time = data.pop('minutes', 0) + (rem_time // 60)
316 data['minutes'] = rem_time % 60
317 rem_time = data.pop('hours', 0) + (rem_time // 60)
318 data['hours'] = rem_time % 24
319 data['days'] += (rem_time // 24)
320 for fn in cls.__PythonFields:
321 if fn in data:
322 if negative_duration:
323 kw[fn] = - data[fn]
324 else:
325 kw[fn] = data[fn]
326 else:
327 kw.pop(fn, None)
328 kw['microseconds'] = data.pop('microseconds', 0)
329 data['seconds'] += kw['microseconds'] / 1000000.0
330
331 rv = super(duration, cls).__new__(cls, **kw)
332 rv.__durationData = data
333 rv.__negativeDuration = negative_duration
334 return rv
335
336 @classmethod
358
359 _PrimitiveDatatypes.append(duration)
360
361 -class _PyXBDateTime_base (basis.simpleTypeDefinition, basis._RepresentAsXsdLiteral_mixin):
362
363 _Lexical_fmt = None
364 """Format for the lexical representation of a date-related instance, excluding timezone.
365
366 Subclasses must define this."""
367
368
369
370
371 __PatternMap = { '%Y' : '(?P<negYear>-?)(?P<year>\d{4,})'
372 , '%m' : '(?P<month>\d{2})'
373 , '%d' : '(?P<day>\d{2})'
374 , '%H' : '(?P<hour>\d{2})'
375 , '%M' : '(?P<minute>\d{2})'
376 , '%S' : '(?P<second>\d{2})(?P<fracsec>\.\d+)?'
377 , '%Z' : '(?P<tzinfo>Z|[-+]\d\d:\d\d)' }
378
379
380
381 __LexicalREMap = { }
382
383
384 __LexicalIntegerFields = ( 'year', 'month', 'day', 'hour', 'minute', 'second' )
385
386 _UTCTimeZone = pyxb.utils.utility.UTCOffsetTimeZone(0)
387 """A L{datetime.tzinfo} instance representing UTC."""
388
389 _LocalTimeZone = pyxb.utils.utility.LocalTimeZone()
390 """A L{datetime.tzinfo} instance representing the local time zone."""
391
392 _DefaultYear = 1900
393 _DefaultMonth = 1
394 _DefaultDay = 1
395
396 @classmethod
425
426 @classmethod
428 for f in fields:
429 kw[f] = getattr(python_value, f)
430 return getattr(super(_PyXBDateTime_base, cls), '_SetKeysFromPython_csc', lambda *a,**kw: None)(python_value, kw, fields)
431
432 @classmethod
435
436
437
438
441
442 @classmethod
444 """Update datetime keywords to account for timezone effects.
445
446 All XML schema timezoned times are in UTC, with the time "in
447 its timezone". If the keywords indicate a non-UTC timezone is
448 in force, and L{pyxb.PreserveInputTimeZone()} has not been
449 set, adjust the values to account for the zone by subtracting
450 the corresponding UTC offset and mark explicitly that the time
451 is in UTC by leaving a C{tzinfo} attribute identifying the UTC
452 time zone.
453
454 @param kw: A dictionary of keywords relevant for a date or
455 time instance. The dictionary is updated by this call.
456 """
457 if pyxb.PreserveInputTimeZone():
458 return
459 tzoffs = kw.pop('tzinfo', None)
460 if tzoffs is not None:
461 use_kw = kw.copy()
462
463 use_kw.setdefault('year', cls._DefaultYear)
464 use_kw.setdefault('month', cls._DefaultMonth)
465 use_kw.setdefault('day', cls._DefaultDay)
466 dt = datetime.datetime(tzinfo=tzoffs, **use_kw)
467 dt -= tzoffs.utcoffset(dt)
468 for k in six.iterkeys(kw):
469 kw[k] = getattr(dt, k)
470 kw['tzinfo'] = cls._UTCTimeZone
471
472 @classmethod
474 iso = value.replace(tzinfo=None).isoformat()
475 if 0 <= iso.find('.'):
476 iso = iso.rstrip('0')
477 if value.tzinfo is not None:
478 iso += value.tzinfo.tzname(value)
479 return iso
480
481 -class dateTime (_PyXBDateTime_base, datetime.datetime):
482 """XMLSchema datatype U{dateTime<http://www.w3.org/TR/xmlschema-2/#dateTime>}.
483
484 This class uses the Python C{datetime.datetime} class as its
485 underlying representation. Unless L{pyxb.PreserveInputTimeZone()}
486 is used, all timezoned dateTime objects are in UTC. Presence of
487 time zone information in the lexical space is preserved by a
488 non-empty tzinfo field, which should always be zero minutes offset
489 from UTC unless the input time zone was preserved.
490
491 @warning: The value space of Python's C{datetime.datetime} class
492 is more restricted than that of C{xs:datetime}. As a specific
493 example, Python does not support negative years or years with more
494 than four digits. For now, the convenience of having an object
495 that is compatible with Python is more important than supporting
496 the full value space. In the future, the choice may be left up to
497 the developer.
498 """
499
500 _XsdBaseType = anySimpleType
501 _ExpandedName = pyxb.namespace.XMLSchema.createExpandedName('dateTime')
502
503 _Lexical_fmt = '%Y-%m-%dT%H:%M:%S'
504 __CtorFields = ( 'year', 'month', 'day', 'hour', 'minute', 'second', 'microsecond', 'tzinfo' )
505
507 args = cls._ConvertArguments(args, kw)
508
509 ctor_kw = { }
510 if kw.get('_nil'):
511 ctor_kw = { 'year': 1900, 'month': 1, 'day': 1 }
512 elif 1 == len(args):
513 value = args[0]
514 if isinstance(value, six.string_types):
515 ctor_kw.update(cls._LexicalToKeywords(value))
516 elif isinstance(value, datetime.datetime):
517 cls._SetKeysFromPython(value, ctor_kw, cls.__CtorFields)
518 elif isinstance(value, six.integer_types):
519 raise TypeError('function takes at least 3 arguments (%d given)' % (len(args),))
520 else:
521 raise SimpleTypeValueError(cls, value)
522 elif 3 <= len(args):
523 for fi in range(len(cls.__CtorFields)):
524 fn = cls.__CtorFields[fi]
525 if fi < len(args):
526 ctor_kw[fn] = args[fi]
527 elif fn in kw:
528 ctor_kw[fn] = kw[fn]
529 kw.pop(fn, None)
530 else:
531 raise TypeError('function takes at least 3 arguments (%d given)' % (len(args),))
532
533 cls._AdjustForTimezone(ctor_kw)
534 kw.update(ctor_kw)
535 year = kw.pop('year')
536 month = kw.pop('month')
537 day = kw.pop('day')
538 rv = super(dateTime, cls).__new__(cls, year, month, day, **kw)
539 return rv
540
541 @classmethod
543 """Return today.
544
545 Just like datetime.datetime.today(), except this one sets a
546 tzinfo field so it's clear the value is UTC."""
547 return cls(datetime.datetime.now(cls._UTCTimeZone))
548
550 """Returns a C{datetime.datetime} instance denoting the same
551 time as this instance but adjusted to be in the local time
552 zone.
553
554 @rtype: C{datetime.datetime} (B{NOT} C{xsd.dateTime})
555 """
556 dt = self
557 if dt.tzinfo is None:
558 dt = dt.replace(tzinfo=self._UTCTimeZone)
559 return dt.astimezone(self._LocalTimeZone)
560
561 _PrimitiveDatatypes.append(dateTime)
562
563 -class time (_PyXBDateTime_base, datetime.time):
564 """XMLSchema datatype U{time<http://www.w3.org/TR/xmlschema-2/#time>}.
565
566 This class uses the Python C{datetime.time} class as its
567 underlying representation. Note that per the XMLSchema spec, all
568 dateTime objects are in UTC, and that timezone information in the
569 string representation in XML is an indication of the local time
570 zone's offset from UTC. Presence of time zone information in the
571 lexical space is indicated by the tzinfo field.
572
573 @note: C{pyxb.PreserveInputTimeZone()} can be used to bypass the
574 normalization to UTC.
575 """
576
577 _XsdBaseType = anySimpleType
578 _ExpandedName = pyxb.namespace.XMLSchema.createExpandedName('time')
579
580 _Lexical_fmt = '%H:%M:%S'
581 __CtorFields = ( 'hour', 'minute', 'second', 'microsecond', 'tzinfo' )
582
584 args = cls._ConvertArguments(args, kw)
585 ctor_kw = { }
586 if 1 <= len(args):
587 value = args[0]
588 if isinstance(value, six.string_types):
589 ctor_kw.update(cls._LexicalToKeywords(value))
590 elif isinstance(value, (datetime.time, datetime.datetime)):
591 cls._SetKeysFromPython(value, ctor_kw, cls.__CtorFields)
592 elif isinstance(value, six.integer_types):
593 for fi in range(len(cls.__CtorFields)):
594 fn = cls.__CtorFields[fi]
595 if fi < len(args):
596 ctor_kw[fn] = args[fi]
597 elif fn in kw:
598 ctor_kw[fn] = kw[fn]
599 kw.pop(fn, None)
600 else:
601 raise SimpleTypeValueError(cls, value)
602
603 cls._AdjustForTimezone(ctor_kw)
604 kw.update(ctor_kw)
605 return super(time, cls).__new__(cls, **kw)
606
607 _PrimitiveDatatypes.append(time)
610 _XsdBaseType = anySimpleType
611
612 _ValidFields = ( 'year', 'month', 'day' )
613
615 args = cls._ConvertArguments(args, kw)
616 ctor_kw = { }
617 ctor_kw['year'] = cls._DefaultYear
618 ctor_kw['month'] = cls._DefaultMonth
619 ctor_kw['day'] = cls._DefaultDay
620 ctor_kw['hour'] = 0
621 ctor_kw['minute'] = 0
622 ctor_kw['second'] = 0
623 if kw.get('_nil'):
624 pass
625 elif 1 <= len(args):
626 value = args[0]
627 if isinstance(value, six.string_types):
628 if 1 != len(args):
629 raise TypeError('construction from string requires exactly 1 argument')
630 ctor_kw.update(cls._LexicalToKeywords(value))
631 elif isinstance(value, (datetime.date, datetime.datetime)):
632 if 1 != len(args):
633 raise TypeError('construction from instance requires exactly 1 argument')
634 cls._SetKeysFromPython(value, ctor_kw, cls._ValidFields)
635 try:
636 tzinfo = value.tzinfo
637 if tzinfo is not None:
638 ctor_kw['tzinfo'] = tzinfo
639 except AttributeError:
640 pass
641 else:
642 fi = 0
643 while fi < len(cls._ValidFields):
644 fn = cls._ValidFields[fi]
645 if fi < len(args):
646 ctor_kw[fn] = args[fi]
647 elif fn in kw:
648 ctor_kw[fn] = kw[fn]
649 kw.pop(fn, None)
650 fi += 1
651 if fi < len(args):
652 ctor_kw['tzinfo'] = args[fi]
653 fi += 1
654 if fi != len(args):
655 raise TypeError('function takes %d arguments plus optional tzinfo (%d given)' % (len(cls._ValidFields), len(args)))
656 else:
657 raise TypeError('function takes %d arguments plus optional tzinfo' % (len(cls._ValidFields),))
658
659
660
661
662
663 kw.update(ctor_kw)
664 argv = []
665 argv.append(kw.pop('year'))
666 argv.append(kw.pop('month'))
667 argv.append(kw.pop('day'))
668 return super(_PyXBDateOnly_base, cls).__new__(cls, *argv, **kw)
669
670 @classmethod
680
681 -class date (_PyXBDateOnly_base):
682 """XMLSchema datatype U{date<http://www.w3.org/TR/xmlschema-2/#date>}.
683
684 This class uses the Python C{datetime.datetime} class as its
685 underlying representation; fields not relevant to this type are
686 derived from 1900-01-01T00:00:00.
687
688 @note: Unlike L{dateTime}, timezoned date values are not converted
689 to UTC. The provided timezone information is retained along with
690 the instance; however, the lexical representation generated for
691 output is canonicalized (timezones no more than 12 hours off UTC).
692 """
693
694 _ExpandedName = pyxb.namespace.XMLSchema.createExpandedName('date')
695 _Lexical_fmt = '%Y-%m-%d'
696 _Fields = ( 'year', 'month', 'day' )
697
698 __SecondsPerMinute = 60
699 __MinutesPerHalfDay = 12 * 60
700 __MinutesPerDay = 24 * 60
702 """Return the recoverable tzinfo for the date.
703
704 Return a L{pyxb.utils.utility.UTCOffsetTimeZone} instance
705 reflecting the timezone associated with the date, or C{None}
706 if the date is not timezoned.
707
708 @note: This is not the recoverable timezone, because timezones are
709 represented as timedeltas which get normalized in ways that
710 don't match what we expect for a tzinfo.
711 """
712 if self.tzinfo is None:
713 return None
714 sdt = self.replace(hour=0, minute=0, second=0, tzinfo=self._UTCTimeZone)
715 utc_offset = (sdt - self).seconds // self.__SecondsPerMinute
716 if utc_offset > self.__MinutesPerHalfDay:
717 utc_offset -= self.__MinutesPerDay
718 return pyxb.utils.utility.UTCOffsetTimeZone(utc_offset)
719
720 @classmethod
738
739 _PrimitiveDatatypes.append(date)
742 """XMLSchema datatype U{gYearMonth<http://www.w3.org/TR/xmlschema-2/#gYearMonth>}.
743
744 This class uses the Python C{datetime.datetime} class as its
745 underlying representation; fields not relevant to this type are
746 derived from 1900-01-01T00:00:00.
747 """
748 _ExpandedName = pyxb.namespace.XMLSchema.createExpandedName('gYearMonth')
749 _Lexical_fmt = '%Y-%m'
750 _ValidFields = ( 'year', 'month' )
751
752 _PrimitiveDatatypes.append(gYearMonth)
753
754 -class gYear (_PyXBDateOnly_base):
755 """XMLSchema datatype U{gYear<http://www.w3.org/TR/xmlschema-2/#gYear>}.
756
757 This class uses the Python C{datetime.datetime} class as its
758 underlying representation; fields not relevant to this type are
759 derived from 1900-01-01T00:00:00.
760 """
761 _ExpandedName = pyxb.namespace.XMLSchema.createExpandedName('gYear')
762 _Lexical_fmt = '%Y'
763 _ValidFields = ( 'year', )
764 _PrimitiveDatatypes.append(gYear)
767 """XMLSchema datatype U{gMonthDay<http://www.w3.org/TR/xmlschema-2/#gMonthDay>}.
768
769 This class uses the Python C{datetime.datetime} class as its
770 underlying representation; fields not relevant to this type are
771 derived from 1900-01-01T00:00:00.
772 """
773 _ExpandedName = pyxb.namespace.XMLSchema.createExpandedName('gMonthDay')
774 _Lexical_fmt = '--%m-%d'
775 _ValidFields = ( 'month', 'day' )
776 _PrimitiveDatatypes.append(gMonthDay)
777
778 -class gDay (_PyXBDateOnly_base):
779 """XMLSchema datatype U{gDay<http://www.w3.org/TR/xmlschema-2/#gDay>}.
780
781 This class uses the Python C{datetime.datetime} class as its
782 underlying representation; fields not relevant to this type are
783 derived from 1900-01-01T00:00:00.
784 """
785 _ExpandedName = pyxb.namespace.XMLSchema.createExpandedName('gDay')
786 _Lexical_fmt = '---%d'
787 _ValidFields = ( 'day', )
788 _PrimitiveDatatypes.append(gDay)
789
790 -class gMonth (_PyXBDateOnly_base):
791 """XMLSchema datatype U{gMonth<http://www.w3.org/TR/xmlschema-2/#gMonth>}.
792
793 This class uses the Python C{datetime.datetime} class as its
794 underlying representation; fields not relevant to this type are
795 derived from 1900-01-01T00:00:00.
796 """
797 _ExpandedName = pyxb.namespace.XMLSchema.createExpandedName('gMonth')
798 _Lexical_fmt = '--%m'
799 _ValidFields = ( 'month', )
800 _PrimitiveDatatypes.append(gMonth)
801
802 -class hexBinary (basis.simpleTypeDefinition, six.binary_type):
803 """XMLSchema datatype U{hexBinary<http://www.w3.org/TR/xmlschema-2/#hexBinary>}."""
804 _XsdBaseType = anySimpleType
805 _ExpandedName = pyxb.namespace.XMLSchema.createExpandedName('hexBinary')
806
807 @classmethod
809 if kw.get('_from_xml', False):
810 xmlt = args[0]
811 try:
812 xmld = xmlt.encode('utf-8')
813 arg0 = binascii.unhexlify(xmld)
814 args = (arg0,) + args[1:]
815 except (TypeError, binascii.Error):
816 raise SimpleTypeValueError(cls, args[0])
817 return args
818
819 @classmethod
821 if isinstance(value, six.text_type):
822 value = value.encode('utf-8')
823 rvd = binascii.hexlify(value)
824 rvt = rvd.decode('utf-8')
825 return rvt.upper()
826
827 @classmethod
830
831 _PrimitiveDatatypes.append(hexBinary)
832
833 -class base64Binary (basis.simpleTypeDefinition, six.binary_type):
880
881 _PrimitiveDatatypes.append(base64Binary)
882
883 -class anyURI (basis.simpleTypeDefinition, six.text_type):
895
896 _PrimitiveDatatypes.append(anyURI)
897
898 -class QName (basis.simpleTypeDefinition, pyxb.namespace.ExpandedName):
899 """XMLSchema datatype U{QName<http://www.w3.org/TR/xmlschema-2/#QName>}."""
900 _XsdBaseType = anySimpleType
901 _ExpandedName = pyxb.namespace.XMLSchema.createExpandedName('QName')
902
903 @classmethod
905 """Section 4.3.1.3: Legacy length return None to indicate no check"""
906 return None
907
908 @classmethod
910 if isinstance(value, pyxb.namespace.ExpandedName):
911 assert 0 > value.localName().find(':')
912 return value
913 if not isinstance(value, six.string_types):
914 raise SimpleTypeValueError(cls, value)
915 if 0 <= value.find(':'):
916 (prefix, local) = value.split(':', 1)
917 if (NCName._ValidRE.match(prefix) is None) or (NCName._ValidRE.match(local) is None):
918 raise SimpleTypeValueError(cls, value)
919 if xmlns_context is None:
920 raise pyxb.QNameResolutionError('QName resolution requires namespace context', value, xmlns_context)
921 return xmlns_context.interpretQName(value, default_no_namespace=True)
922 if NCName._ValidRE.match(value) is None:
923 raise SimpleTypeValueError(cls, value)
924 if xmlns_context is not None:
925 return xmlns_context.interpretQName(value, default_no_namespace=True)
926 return pyxb.namespace.ExpandedName(value)
927
928 @classmethod
930 if 1 == len(args):
931 xmlns_context = kw.pop('_xmlns_context', pyxb.namespace.NamespaceContext.Current())
932 args = (cls._ConvertIf(args[0], xmlns_context),)
933 super_fn = getattr(super(QName, cls), '_ConvertArguments_vx', lambda *a,**kw: args)
934 return super_fn(args, kw)
935
936 @classmethod
938
939
940
941
942
943 raise pyxb.UsageError('Cannot represent QName without namespace declaration')
944
945 @classmethod
949
950
951 _PrimitiveDatatypes.append(QName)
952
953 -class NOTATION (basis.simpleTypeDefinition):
962
963 _PrimitiveDatatypes.append(NOTATION)
966 """XMLSchema datatype U{normalizedString<http:///www.w3.org/TR/xmlschema-2/#normalizedString>}.
967
968 Normalized strings can't have carriage returns, linefeeds, or
969 tabs in them."""
970
971
972
973
974
975
976
977
978
979
980 _ExpandedName = pyxb.namespace.XMLSchema.createExpandedName('normalizedString')
981
982
983
984
985 __BadChars = re.compile("[\r\n\t]")
986
987 _ValidRE = None
988 _InvalidRE = None
989
990 @classmethod
1006
1007 @classmethod
1009 """Post-extended method to validate that a string matches a given pattern.
1010
1011 If you can express the valid strings as a compiled regular
1012 expression in the class variable _ValidRE, or the invalid
1013 strings as a compiled regular expression in the class variable
1014 _InvalidRE, you can just use those. If the acceptable matches
1015 are any trickier, you should invoke the superclass
1016 implementation, and if it returns True then perform additional
1017 tests."""
1018 super_fn = getattr(super(normalizedString, cls), '_ValidateString_va', lambda *a,**kw: True)
1019 if not super_fn(value):
1020 return False
1021 return cls.__ValidateString(value)
1022
1023 @classmethod
1031
1032 _DerivedDatatypes.append(normalizedString)
1033 assert normalizedString.XsdSuperType() == string
1034
1035 -class token (normalizedString):
1036 """XMLSchema datatype U{token<http:///www.w3.org/TR/xmlschema-2/#token>}.
1037
1038 Tokens cannot leading or trailing space characters; any
1039 carriage return, line feed, or tab characters; nor any occurrence
1040 of two or more consecutive space characters."""
1041
1042 _ExpandedName = pyxb.namespace.XMLSchema.createExpandedName('token')
1043
1044 @classmethod
1046 super_fn = getattr(super(token, cls), '_ValidateString_va', lambda *a,**kw: True)
1047 if not super_fn(value):
1048 return False
1049 if value.startswith(" ") \
1050 or value.endswith(" ") \
1051 or (0 <= value.find(' ')):
1052 raise SimpleTypeValueError(cls, value)
1053 return True
1054 _DerivedDatatypes.append(token)
1060 _DerivedDatatypes.append(language)
1071 _DerivedDatatypes.append(NMTOKEN)
1075 _ListDatatypes.append(NMTOKENS)
1076
1077 -class Name (token):
1083 _DerivedDatatypes.append(Name)
1091 _DerivedDatatypes.append(NCName)
1092
1093 -class ID (NCName):
1098 _DerivedDatatypes.append(ID)
1099
1100 -class IDREF (NCName):
1105 _DerivedDatatypes.append(IDREF)
1106
1107 -class IDREFS (basis.STD_list):
1111 _ListDatatypes.append(IDREFS)
1123 _DerivedDatatypes.append(ENTITY)
1129 _ListDatatypes.append(ENTITIES)
1130
1131 -class integer (basis.simpleTypeDefinition, six.long_type):
1139
1140 _DerivedDatatypes.append(integer)
1145 _DerivedDatatypes.append(nonPositiveInteger)
1150 _DerivedDatatypes.append(negativeInteger)
1151
1152 -class long (integer):
1155 _DerivedDatatypes.append(long)
1156
1157 -class int (basis.simpleTypeDefinition, six.int_type):
1167 _DerivedDatatypes.append(int)
1172 _DerivedDatatypes.append(short)
1173
1174 -class byte (short):
1177 _DerivedDatatypes.append(byte)
1182 _DerivedDatatypes.append(nonNegativeInteger)
1187 _DerivedDatatypes.append(unsignedLong)
1192 _DerivedDatatypes.append(unsignedInt)
1197 _DerivedDatatypes.append(unsignedShort)
1202 _DerivedDatatypes.append(unsignedByte)
1207 _DerivedDatatypes.append(positiveInteger)
1208
1209 from . import content
1210
1211 -class anyType (basis.complexTypeDefinition):
1219
1221
1222 global _BuildAutomaton
1223 del _BuildAutomaton
1224 import pyxb.utils.fac as fac
1225
1226 counters = set()
1227 cc_0 = fac.CounterCondition(min=0, max=None, metadata=pyxb.utils.utility.Location('http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/#key-urType', 1, 1))
1228 counters.add(cc_0)
1229 states = set()
1230 final_update = set()
1231 final_update.add(fac.UpdateInstruction(cc_0, False))
1232 symbol = content.WildcardUse(content.Wildcard(process_contents=content.Wildcard.PC_lax, namespace_constraint=content.Wildcard.NC_any), None)
1233 st_0 = fac.State(symbol, is_initial=True, final_update=final_update, is_unordered_catenation=False)
1234 states.add(st_0)
1235 transitions = set()
1236 transitions.add(fac.Transition(st_0, [
1237 fac.UpdateInstruction(cc_0, True) ]))
1238 st_0._set_transitionSet(transitions)
1239 return fac.Automaton(states, counters, True, containing_state=None)
1240 anyType._Automaton = _BuildAutomaton()
1241
1242
1243
1244
1245 anyType._IsUrType = classmethod(lambda _c: _c == anyType)
1246