1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """Extensions of standard exceptions for PyXB events.
17
18 Yeah, I'd love this module to be named exceptions.py, but it can't
19 because the standard library has one of those, and we need to
20 reference it below.
21 """
22
23 import exceptions
26 """Base class for exceptions that indicate a problem that the user should fix."""
27
28 """The arguments passed to the exception constructor."""
29 _args = None
30
31 """The keywords passed to the exception constructor.
32
33 @note: Do not pop values from the keywords array in subclass
34 constructors that recognize and extract values from them. They
35 should be kept around so they're accessible generically."""
36 _kw = None
37
39 """Create an exception indicating a PyXB-related problem.
40
41 If no args are present, a default argument is taken from the
42 C{message} keyword.
43
44 @keyword message : Text to provide the user with information about the problem.
45 """
46 if 0 == len(args) and 'message' in kw:
47 args = (kw.pop('message'),)
48 self._args = args
49 self._kw = kw
50 exceptions.Exception.__init__(self, *args)
51
53 """Raised when the XML hierarchy does not appear to be valid for an XML schema."""
54 pass
55
57 """Violation of some rule relevant to XML Namespaces"""
58 - def __init__ (self, namespace, *args, **kw):
61
63
65 """Problem related to namespace archives"""
66 pass
67
69 """Raised when somebody tries to create a schema component using a
70 schema that has already been used in that namespace. Import and
71 include processing would have avoided this, so somebody asked for
72 it specifically."""
73 - def __init__ (self, namespace, schema_location, existing_schema, *args, **kw):
81
85
87 """Raised when something goes wrong generating the binding classes"""
88 pass
89
91 """Raised when an attempt is made to record multiple objects of the same name in the same namespace category."""
92 pass
93
95 '''Raised when a name is referenced that is not defined in the appropriate namespace.'''
96 __namespace = None
97 __ncName = None
98
100 """Raised when processing document content and an error is encountered."""
101 pass
102
104 """Raised when processing document and the content model is not satisfied."""
105 @property
107 """The L{pyxb.binding.content.ElementDeclaration} instance to which the content should conform, if available."""
108 return self.__elementUse
109
110 @property
112 """The L{pyxb.binding.basis.complexTypeDefinition} instance to which the content would belong, if available."""
113 return self.__container
114
115 @property
116 - def content (self):
117 """The value which could not be reconciled with the content model."""
118 return self.__content
119
121 """Raised when processing document and the content model is not satisfied.
122
123 @keyword content : The value that could not be reconciled with the content model
124 @keyword container : Optional binding instance into which the content was to be assigned
125 @keyword element_use : Optional reference to an element use identifying the element to which the value was to be reconciled
126 """
127 self.__content = kw.pop('content', None)
128 if args:
129 self.__content = args[0]
130 self.__container = kw.pop('container', None)
131 self.__elementUse = kw.pop('element_use', None)
132 if self.__content is not None:
133 if self.__container is not None:
134 kw.setdefault('message', '%s cannot accept wildcard content %s' % (self.__container, self.__content))
135 elif self.__elementUse is not None:
136 kw.setdefault('message', '%s not consistent with content model for %s' % (self.__content, self.__elementUse))
137 else:
138 kw.setdefault('message', str(self.__content))
139 BadDocumentError.__init__(self, **kw)
140
142 """A root DOM node could not be resolved to a schema element"""
143
144 node = None
145 """The L{xml.dom.Element} instance that could not be recognized"""
146
151 node_name = property(__get_node_name)
152
157
159 """Raised when something in the infoset fails to satisfy a content model or attribute requirement.
160
161 All validation errors include a L{location} attribute which shows
162 where in the original XML the problem occurred. The attribute may
163 be C{None} if the content did not come from an XML document, or
164 the underlying XML infrastructure did not provide a location.
165
166 More refined validation error exception classes add more attributes."""
167
168 location = None
169 """Where the error occurred in the document being parsed, if
170 available. This will be C{None}, or an instance of
171 L{pyxb.utils.utility.Location}."""
172
174 """Provide information describing why validation failed.
175
176 In many cases, this is simple the informal string content that
177 would be obtained through the C{str} built-in function. For
178 certain errors this method gives more details on what would be
179 acceptable and where the descriptions can be found in the
180 original schema.
181
182 @return: a string description of validation failure"""
183 return str(self)
184
186 """Raised when a validation requirement for an element is not satisfied."""
187 pass
188
190 """Attempt to create an instance of an abstract element.
191
192 Raised when an element is created and the identified binding is
193 abstract. Such elements cannot be created directly; instead the
194 creation must derive from an instance of the abstract element's
195 substitution group.
196
197 Since members of the substitution group self-identify using the
198 C{substitutionGroup} attribute, there is no general way to find
199 the set of elements which would be acceptable in place of the
200 abstract element."""
201
202 element = None
203 """The abstract L{pyxb.binding.basis.element} in question"""
204
205 value = None
206 """The value proposed for the L{element}. This is usually going
207 to be a C{xml.dom.Node} used in the attempt to create the element,
208 C{None} if the abstract element was invoked without a node, or
209 another type if
210 L{pyxb.binding.content.ElementDeclaration.toDOM} is
211 mis-used."""
212
213 - def __init__ (self, element, location, value=None):
221
223 return 'Cannot instantiate abstract element %s directly' % (self.element.name(),)
224
225 -class ContentInNilInstanceError (ElementValidationError):
226 """Raised when an element that is marked to be nil is assigned content."""
227
228 instance = None
229 """The binding instance which is xsi:nil"""
230
231 content = None
232 """The content that was to be assigned to the instance."""
233
234 - def __init__ (self, instance, content, location=None):
235 """@param instance: the value for the L{instance} attribute.
236 @param content: the value for the L{content} attribute.
237 @param location: the value for the L{location} attribute. Default taken from C{instance} if possible."""
238
239 self.instance = instance
240 self.content = content
241 if location is None:
242 location = self.instance._location()
243 self.location = location
244 super(ContentInNilInstanceError, self).__init__(instance, content, location)
245
246 - def __str__ (self):
247 from pyxb.namespace.builtin import XMLSchema_instance as XSI
248 return '%s with %s=true cannot have content' % (self.instance._diagnosticName(), XSI.nil)
249
251 """Raised when invoking L{_setIsNil<pyxb.binding.basis._TypeBinding_mixin._setIsNil>} on a type that does not support nillable."""
252
253 instance = None
254 """The binding instance on which an inappropriate operation was invoked."""
255
256 - def __init__ (self, instance, location=None):
264
266 """Raised when a validation requirement for a complex type is not satisfied."""
267 pass
268
270 """Attempt to create an instance of an abstract complex type.
271
272 These types are analogous to abstract base classes, and cannot be
273 created directly. A type should be used that extends the abstract
274 class.
275
276 When an incoming document is missing the xsi:type attribute which
277 redirects an element with an abstract type to the correct type,
278 the L{node} attribute is provided so the user can get a clue as to
279 where the problem occured. When this exception is a result of
280 constructor mis-use in Python code, the traceback will tell you
281 where the problem lies.
282 """
283
284 type = None
285 """The abstract L{pyxb.binding.basis.complexTypeDefinition} subclass used."""
286
287 node = None
288 """The L{xml.dom.Element} from which instantiation was attempted, if available."""
289
290 - def __init__ (self, type, location, node):
298
300
301 return 'Cannot instantiate abstract type %s directly' % (self.type._ExpandedName,)
302
304 """Attempt made to set an attribute on an element with simple type.
305
306 Note that elements with complex type and simple content may have
307 attributes; elements with simple type must not."""
308
309 instance = None
310 """The simple type binding instance on which no attributes exist."""
311
312 tag = None
313 """The name of the proposed attribute."""
314
315 value = None
316 """The value proposed to be assigned to the non-existent attribute."""
317
318 - def __init__ (self, instance, tag, value, location=None):
331
333 return 'Simple type %s cannot support attribute %s' % (self.instance._Name(), self.tag)
334
335 -class ContentValidationError (ComplexTypeValidationError):
336 """Violation of a complex type content model."""
337 pass
338
339 -class SimpleContentAbsentError (ContentValidationError):
340 """An instance with simple content was not provided with a value."""
341
342 instance = None
343 """The binding instance for which simple content is missing."""
344
345 - def __init__ (self, instance, location):
346 """@param instance: the value for the L{instance} attribute.
347 @param location: the value for the L{location} attribute."""
348 self.instance = instance
349 self.location = location
350 super(SimpleContentAbsentError, self).__init__(instance, location)
351
352 - def __str__ (self):
353 return 'Type %s requires content' % (self.instance._Name(),)
354
356 """A complex type with simple content was provided too much content."""
357
358 instance = None
359 """The binding instance that already has simple content assigned."""
360
361 value = None
362 """The proposed addition to that simple content."""
363
365 """@param instance: the value for the L{instance} attribute.
366 @param value: the value for the L{value} attribute.
367 @param location: the value for the L{location} attribute."""
368 self.instance = instance
369 self.value = value
370 self.location = location
371 super(ExtraSimpleContentError, self).__init__(instance, value, location)
372
374 return 'Instance of %s already has simple content value assigned' % (self.instance._Name(),)
375
376 -class MixedContentError (ContentValidationError):
377 """Non-element content added to a complex type instance that does not support mixed content."""
378
379 instance = None
380 """The binding instance."""
381
382 value = None
383 """The non-element content."""
384
385 - def __init__ (self, instance, value, location=None):
386 """@param instance: the value for the L{instance} attribute.
387 @param value: the value for the L{value} attribute.
388 @param location: the value for the L{location} attribute."""
389 self.instance = instance
390 self.value = value
391 self.location = location
392 super(MixedContentError, self).__init__(instance, value, location)
393
394 - def __str__ (self):
395 if self.location is not None:
396 return 'Invalid non-element content at %s' % (self.location,)
397 return 'Invalid non-element content'
398
399 -class UnprocessedKeywordContentError (ContentValidationError):
400 """A complex type constructor was provided with keywords that could not be recognized."""
401
402 instance = None
403 """The binding instance being constructed."""
404
405 keywords = None
406 """The keywords that could not be recognized. These may have been
407 intended to be attributes or elements, but cannot be identified as
408 either."""
409
410 - def __init__ (self, instance, keywords, location=None):
411 """@param instance: the value for the L{instance} attribute.
412 @param keywords: the value for the L{keywords} attribute.
413 @param location: the value for the L{location} attribute."""
414 self.instance = instance
415 self.keywords = keywords
416 self.location = location
417 super(UnprocessedKeywordContentError, self).__init__(instance, keywords, location)
418
419 - def __str__ (self):
420 return 'Unprocessed keywords instantiating %s: %s' % (self.instance._Name(), ' '.join(self.keywords.keys()))
421
422 -class IncrementalElementContentError (ContentValidationError):
423 """Element or element-like content could not be validly associated with an sub-element in the content model.
424
425 This exception occurs when content is added to an element during
426 incremental validation, such as when positional arguments are used
427 in a constructor or material is appended either explicitly or
428 through parsing a DOM instance."""
429
430 instance = None
431 """The binding for which the L{value} could not be associated with an element."""
432
433 automaton_configuration = None
434 """The L{pyxb.binding.content.AutomatonConfiguration} representing the current state of the L{instance} content."""
435
436 value = None
437 """The value that could not be associated with allowable content."""
438
439 - def __init__ (self, instance, automaton_configuration, value, location=None):
440 """@param instance: the value for the L{instance} attribute.
441 @param automaton_configuration: the value for the L{automaton_configuration} attribute.
442 @param value: the value for the L{value} attribute.
443 @param location: the value for the L{location} attribute."""
444 self.instance = instance
445 self.automaton_configuration = automaton_configuration
446 self.value = value
447 self.location = location
448 super(IncrementalElementContentError, self).__init__(instance, automaton_configuration, value, location)
449
450 -class UnrecognizedContentError (IncrementalElementContentError):
451 """Element or element-like content could not be validly associated with an sub-element in the content model.
452
453 This exception occurs when content is added to an element during incremental validation."""
454
455 - def __str__ (self):
456 value = self.value
457 try:
458 value = str(self.value._element().name())
459 except:
460 pass
461 acceptable = self.automaton_configuration.acceptableContent()
462 if 0 == acceptable:
463 expect = 'no more content'
464 else:
465 import pyxb.binding.content
466 seen = set()
467 names = []
468 for u in acceptable:
469 if isinstance(u, pyxb.binding.content.ElementUse):
470 n = str(u.elementBinding().name())
471 else:
472 assert isinstance(u, pyxb.binding.content.WildcardUse)
473 n = 'xs:any'
474 if not (n in seen):
475 names.append(n)
476 seen.add(n)
477 expect = ' or '.join(names)
478 location = ''
479 if self.location is not None:
480 location = ' at %s' % (self.location,)
481 return 'Invalid content %s%s (expect %s)' % (value, location, expect)
482
483 - def details (self):
484 import pyxb.binding.basis
485 import pyxb.binding.content
486 i = self.instance
487 rv = [ ]
488 if i._element() is not None:
489 rv.append('The containing element %s is defined at %s.' % (i._element().name(), i._element().xsdLocation()))
490 rv.append('The containing element type %s is defined at %s' % (self.instance._Name(), str(self.instance._XSDLocation)))
491 if self.location is not None:
492 rv.append('The unrecognized content %s begins at %s' % (self.value._diagnosticName(), self.location))
493 else:
494 rv.append('The unrecognized content is %s' % (self.value._diagnosticName(),))
495 ty = type(self.instance)
496 rv.append('The %s automaton %s in an accepting state.' % (self.instance._Name(), self.automaton_configuration.isAccepting() and "is" or "is not"))
497 if isinstance(self.instance, pyxb.binding.basis.complexTypeDefinition) and self.instance._IsMixed():
498 rv.append('Character information content would be permitted.')
499 acceptable = self.automaton_configuration.acceptableContent()
500 if 0 == len(acceptable):
501 rv.append('No elements or wildcards would be accepted at this point.')
502 else:
503 rv.append('The following element and wildcard content would be accepted:')
504 rv2 = []
505 for u in acceptable:
506 if isinstance(u, pyxb.binding.content.ElementUse):
507 rv2.append('An element %s per %s' % (u.elementBinding().name(), u.xsdLocation()))
508 else:
509 assert isinstance(u, pyxb.binding.content.WildcardUse)
510 rv2.append('A wildcard per %s' % (u.xsdLocation(),))
511 rv.append('\t' + '\n\t'.join(rv2))
512 return '\n'.join(rv)
513
514 -class BatchElementContentError (ContentValidationError):
515 """Element/wildcard content cannot be reconciled with the required content model.
516
517 This exception occurs in post-construction validation using a
518 fresh validating automaton."""
519
520 instance = None
521 """The binding instance being constructed."""
522
523 automaton_configuration = None
524 """The L{pyxb.binding.content.AutomatonConfiguration} representing the current state of the L{instance} content."""
525
526 symbols = None
527 """The sequence of symbols that were accepted as content prior to the error."""
528
529 symbol_set = None
530 """The leftovers from L{pyxb.binding.basis.complexTypeDefinition._symbolSet} that could not be reconciled with the content model."""
531
532 - def __init__ (self, instance, automaton_configuration, symbols, symbol_set):
533 """@param instance: the value for the L{instance} attribute.
534 @param automaton_configuration: the value for the L{automaton_configuration} attribute.
535 @param symbols: the value for the L{symbols} attribute.
536 @param symbol_set: the value for the L{symbol_set} attribute."""
537 self.instance = instance
538 self.automaton_configuration = automaton_configuration
539 self.symbols = symbols
540 self.symbol_set = symbol_set
541 super(BatchElementContentError, self).__init__(instance, automaton_configuration, symbols, symbol_set)
542
543 - def details (self):
544 import pyxb.binding.basis
545 import pyxb.binding.content
546 i = self.instance
547 rv = [ ]
548 if i._element() is not None:
549 rv.append('The containing element %s is defined at %s.' % (i._element().name(), i._element().xsdLocation()))
550 rv.append('The containing element type %s is defined at %s' % (self.instance._Name(), str(self.instance._XSDLocation)))
551 ty = type(self.instance)
552 rv.append('The %s automaton %s in an accepting state.' % (self.instance._Name(), self.automaton_configuration.isAccepting() and "is" or "is not"))
553 if 0 == len(self.symbols):
554 rv.append('No content has been accepted')
555 else:
556 rv.append('The last accepted content was %s' % (self.symbols[-1][1]._diagnosticName(),))
557 if isinstance(self.instance, pyxb.binding.basis.complexTypeDefinition) and self.instance._IsMixed():
558 rv.append('Character information content would be permitted.')
559 acceptable = self.automaton_configuration.acceptableSymbols()
560 if 0 == len(acceptable):
561 rv.append('No elements or wildcards would be accepted at this point.')
562 else:
563 rv.append('The following element and wildcard content would be accepted:')
564 rv2 = []
565 for u in acceptable:
566 if isinstance(u, pyxb.binding.content.ElementUse):
567 rv2.append('An element %s per %s' % (u.elementBinding().name(), u.xsdLocation()))
568 else:
569 assert isinstance(u, pyxb.binding.content.WildcardUse)
570 rv2.append('A wildcard per %s' % (u.xsdLocation(),))
571 rv.append('\t' + '\n\t'.join(rv2))
572 if 0 == len(self.symbol_set):
573 rv.append('No content remains unconsumed')
574 else:
575 rv.append('The following content was not processed by the automaton:')
576 rv2 = []
577 for (ed, syms) in self.symbol_set.iteritems():
578 if ed is None:
579 rv2.append('xs:any (%u instances)' % (len(syms),))
580 else:
581 rv2.append('%s (%u instances)' % (ed.name(), len(syms)))
582 rv.append('\t' + '\n\t'.join(rv2))
583 return '\n'.join(rv)
584
585 -class IncompleteElementContentError (BatchElementContentError):
586 """Validation of an instance failed to produce an accepting state.
587
588 This exception occurs in batch-mode validation."""
589 pass
590
591 -class UnprocessedElementContentError (BatchElementContentError):
592 """Validation of an instance produced an accepting state but left element material unconsumed.
593
594 This exception occurs in batch-mode validation."""
595 pass
596
598 """Raised when a simple type value does not satisfy its constraints."""
599 type = None
600 """The L{pyxb.binding.basis.simpleTypeDefinition} that constrains values."""
601
602 value = None
603 """The value that violates the constraints of L{type}. In some
604 cases this is a tuple of arguments passed to a constructor that
605 failed with a built-in exception likeC{ValueError} or
606 C{OverflowError}."""
607
608 - def __init__ (self, type, value, location=None):
619
621 """Raised when a list simple type contains a member that does not satisfy its constraints.
622
623 In this case, L{type} is the type of the list, and value
624 C{type._ItemType} is the type for which the L{value} is
625 unacceptable."""
626
629
631 """Raised when a union simple type contains a member that does not satisfy its constraints.
632
633 In this case, L{type} is the type of the union, and the value
634 C{type._MemberTypes} is the set of types for which the value is
635 unacceptable.
636
637 The L{value} itself is the tuple of arguments passed to the
638 constructor for the union."""
639
641 return 'No memberType of %s can be constructed from %s' % (self.type._Name(), self.value)
642
644 """Raised when a simple type value does not satisfy a facet constraint.
645
646 This extends L{SimpleTypeValueError} with the L{facet} field which
647 can be used to determine why the value is unacceptable."""
648
649 type = None
650 """The L{pyxb.binding.basis.simpleTypeDefinition} that constrains values."""
651
652 value = None
653 """The value that violates the constraints of L{type}. In some
654 cases this is a tuple of arguments passed to a constructor that
655 failed with a built-in exception likeC{ValueError} or
656 C{OverflowError}."""
657
658 facet = None
659 """The specific facet that is violated by the value."""
660
661 - def __init__ (self, type, value, facet, location=None):
676
679
681 """Raised when context requires a plural value.
682
683 Unlike L{SimpleListValueError}, in this case the plurality is
684 external to C{type}, for example when an element has simple
685 content and allows multiple occurrences."""
686 pass
687
689 """Raised when an attribute requirement is not satisfied."""
690
691 type = None
692 """The L{pyxb.binding.basis.complexTypeDefinition} subclass of the instance."""
693
694 tag = None
695 """The name of the attribute."""
696
697 instance = None
698 """The binding instance, if available."""
699
700 - def __init__ (self, type, tag, instance=None, location=None):
714
716 """Attempt to reference an attribute not sanctioned by content model."""
717 pass
718
720 """Raised when an attribute that is prohibited is set or referenced in an element."""
722 return 'Attempt to reference prohibited attribute %s in type %s' % (self.tag, self.type)
723
725 """Raised when an attribute that is required is missing in an element."""
727 return 'Instance of %s lacks required attribute %s' % (self.type, self.tag)
728
730 """Attempt to change an attribute that has a fixed value constraint."""
732 return 'Cannot change fixed attribute %s in type %s' % (self.tag, self.type)
733
735 """Raised when the bindings are mis-used.
736
737 These are not validation errors, but rather structural errors.
738 For example, attempts to extract complex content from a type that
739 requires simple content, or vice versa. """
740
741 -class NotSimpleContentError (BindingError):
742 """An operation that requires simple content was invoked on a
743 complex type instance that does not have simple content."""
744
745 instance = None
746 """The binding instance which should have had simple content."""
747
748 - def __init__ (self, instance):
749 """@param instance: the binding instance that was mis-used.
750 This will be available in the L{instance} attribute."""
751 self.instance = instance
752 super(BindingError, self).__init__(instance)
753 pass
754
755 - def __str__ (self):
756 return 'type %s does not have simple content' % (self.instance._Name(),)
757
758 -class NotComplexContentError (BindingError):
759 """An operation that requires a content model was invoked on a
760 complex type instance that has empty or simple content."""
761
762 instance = None
763 """The binding instance which should have had a content model."""
764
765 - def __init__ (self, instance):
766 """@param instance: the binding instance that was mis-used.
767 This will be available in the L{instance} attribute."""
768 self.instance = instance
769 super(BindingError, self).__init__(instance)
770
771 - def __str__ (self):
772 return 'type %s has simple/empty content' % (self.instance._Name(),)
773
775 """Reserved name set in binding instance."""
776
777 instance = None
778 """The binding instance."""
779
780 name = None
781 """The name that was caught being assigned"""
782
789
792
794 """Base class for exceptions that indicate a problem that the user probably can't fix."""
795 pass
796
798 """Raised when the code detects user violation of an API."""
799
801 """Raised when the code detects an implementation problem."""
802
804 """Raised when required capability has not been implemented.
805
806 This is only used where it is reasonable to expect the capability
807 to be present, such as a feature of XML schema that is not
808 supported (e.g., the redefine directive)."""
809