Package pyxb :: Module exceptions_
[hide private]
[frames] | no frames]

Source Code for Module pyxb.exceptions_

   1  # -*- coding: utf-8 -*- 
   2  # Copyright 2009-2013, Peter A. Bigot 
   3  # 
   4  # Licensed under the Apache License, Version 2.0 (the "License"); you may 
   5  # not use this file except in compliance with the License. You may obtain a 
   6  # copy of the License at: 
   7  # 
   8  #            http://www.apache.org/licenses/LICENSE-2.0 
   9  # 
  10  # Unless required by applicable law or agreed to in writing, software 
  11  # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
  12  # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
  13  # License for the specific language governing permissions and limitations 
  14  # under the License. 
  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 pyxb 
  24  from pyxb.utils import six 
25 26 -class PyXBException (Exception):
27 """Base class for exceptions that indicate a problem that the user should fix.""" 28 29 """The arguments passed to the exception constructor.""" 30 _args = None 31 32 """The keywords passed to the exception constructor. 33 34 @note: Do not pop values from the keywords array in subclass 35 constructors that recognize and extract values from them. They 36 should be kept around so they're accessible generically.""" 37 _kw = None 38
39 - def __init__ (self, *args, **kw):
40 """Create an exception indicating a PyXB-related problem. 41 42 If no args are present, a default argument is taken from the 43 C{message} keyword. 44 45 @keyword message : Text to provide the user with information about the problem. 46 """ 47 if 0 == len(args) and 'message' in kw: 48 args = (kw.pop('message'),) 49 self._args = args 50 self._kw = kw 51 super(PyXBException, self).__init__(*args)
52 53 if six.PY2:
54 - def _str_from_unicode (self):
55 return unicode(self).encode(pyxb._OutputEncoding)
56
57 -class PyXBVersionError (PyXBException):
58 """Raised on import of a binding generated with a different version of PYXB""" 59 pass
60
61 -class DOMGenerationError (PyXBException):
62 """A non-validation error encountered converting bindings to DOM.""" 63 pass
64
65 @six.python_2_unicode_compatible 66 -class UnboundElementError (DOMGenerationError):
67 """An instance converting to DOM had no bound element.""" 68 69 instance = None 70 """The binding instance. This is missing an element binding (via 71 L{pyxb.binding.basis._TypeBinding_mixin._element}) and no 72 C{element_name} was passed.""" 73
74 - def __init__ (self, instance):
77
78 - def __str__ (self):
79 return six.u('Instance of type %s has no bound element for start tag') % (self.instance._diagnosticName(),)
80
81 -class SchemaValidationError (PyXBException):
82 """Raised when the XML hierarchy does not appear to be valid for an XML schema.""" 83 pass
84
85 -class NamespaceError (PyXBException):
86 """Violation of some rule relevant to XML Namespaces"""
87 - def __init__ (self, namespace, *args, **kw):
88 PyXBException.__init__(self, *args, **kw) 89 self.__namespace = namespace
90
91 - def namespace (self): return self.__namespace
92
93 -class NamespaceArchiveError (PyXBException):
94 """Problem related to namespace archives""" 95 pass
96
97 -class SchemaUniquenessError (PyXBException):
98 """Raised when somebody tries to create a schema component using a 99 schema that has already been used in that namespace. Import and 100 include processing would have avoided this, so somebody asked for 101 it specifically."""
102 - def __init__ (self, namespace, schema_location, existing_schema, *args, **kw):
103 super(SchemaUniquenessError, self).__init__(*args, **kw) 104 self.__namespace = namespace 105 self.__schemaLocation = schema_location 106 self.__existingSchema = existing_schema
107
108 - def namespace (self): return self.__namespace
109 - def schemaLocation (self): return self.__schemaLocation
110 - def existingSchema (self): return self.__existingSchema
111
112 -class BindingGenerationError (PyXBException):
113 """Raised when something goes wrong generating the binding classes""" 114 pass
115
116 -class NamespaceUniquenessError (NamespaceError):
117 """Raised when an attempt is made to record multiple objects of the same name in the same namespace category.""" 118 pass
119
120 -class NotInNamespaceError (PyXBException):
121 '''Raised when a name is referenced that is not defined in the appropriate namespace.''' 122 __namespace = None 123 __ncName = None
124
125 -class QNameResolutionError (NamespaceError):
126 '''Raised when a QName cannot be associated with a namespace.''' 127 namespaceContext = None 128 qname = None 129
130 - def __init__ (self, message, qname, xmlns_context):
131 self.qname = qname 132 self.namespaceContext = xmlns_context 133 super(QNameResolutionError, self).__init__(message, qname, xmlns_context)
134
135 -class BadDocumentError (PyXBException):
136 """Raised when processing document content and an error is encountered.""" 137 pass
138
139 -class StructuralBadDocumentError (BadDocumentError):
140 """Raised when processing document and the content model is not satisfied.""" 141 @property
142 - def element_use (self):
143 """The L{pyxb.binding.content.ElementDeclaration} instance to which the content should conform, if available.""" 144 return self.__elementUse
145 146 @property
147 - def container (self):
148 """The L{pyxb.binding.basis.complexTypeDefinition} instance to which the content would belong, if available.""" 149 return self.__container
150 151 @property
152 - def content (self):
153 """The value which could not be reconciled with the content model.""" 154 return self.__content
155
156 - def __init__ (self, *args, **kw):
157 """Raised when processing document and the content model is not satisfied. 158 159 @keyword content : The value that could not be reconciled with the content model 160 @keyword container : Optional binding instance into which the content was to be assigned 161 @keyword element_use : Optional reference to an element use identifying the element to which the value was to be reconciled 162 """ 163 self.__content = kw.pop('content', None) 164 if args: 165 self.__content = args[0] 166 self.__container = kw.pop('container', None) 167 self.__elementUse = kw.pop('element_use', None) 168 if self.__content is not None: 169 if self.__container is not None: 170 kw.setdefault('message', '%s cannot accept wildcard content %s' % (self.__container._Name(), self.__content)) 171 elif self.__elementUse is not None: 172 kw.setdefault('message', '%s not consistent with content model for %s' % (self.__content, self.__elementUse)) 173 else: 174 kw.setdefault('message', six.text_type(self.__content)) 175 BadDocumentError.__init__(self, **kw)
176
177 -class UnrecognizedDOMRootNodeError (StructuralBadDocumentError):
178 """A root DOM node could not be resolved to a schema element""" 179 180 node = None 181 """The L{xml.dom.Element} instance that could not be recognized""" 182
183 - def __get_node_name (self):
184 """The QName of the L{node} as a L{pyxb.namespace.ExpandedName}""" 185 import pyxb.namespace 186 return pyxb.namespace.ExpandedName(self.node.namespaceURI, self.node.localName)
187 node_name = property(__get_node_name) 188
189 - def __init__ (self, node):
190 """@param node: the value for the L{node} attribute.""" 191 self.node = node 192 super(UnrecognizedDOMRootNodeError, self).__init__(node)
193
194 -class ValidationError (PyXBException):
195 """Raised when something in the infoset fails to satisfy a content model or attribute requirement. 196 197 All validation errors include a L{location} attribute which shows 198 where in the original XML the problem occurred. The attribute may 199 be C{None} if the content did not come from an XML document, or 200 the underlying XML infrastructure did not provide a location. 201 202 More refined validation error exception classes add more attributes.""" 203 204 location = None 205 """Where the error occurred in the document being parsed, if 206 available. This will be C{None}, or an instance of 207 L{pyxb.utils.utility.Location}.""" 208
209 - def details (self):
210 """Provide information describing why validation failed. 211 212 In many cases, this is simply the informal string content that 213 would be obtained through the C{str} built-in function. For 214 certain errors this method gives more details on what would be 215 acceptable and where the descriptions can be found in the 216 original schema. 217 218 @return: a string description of validation failure""" 219 return six.text_type(self)
220
221 @six.python_2_unicode_compatible 222 -class NonElementValidationError (ValidationError):
223 """Raised when an element (or a value bound to an element) appears 224 in context that does not permit an element.""" 225 226 element = None 227 """The content that is not permitted. This may be an element, or 228 a DOM representation that would have been made into an element had 229 matters progressed further.""" 230
231 - def __init__ (self, element, location=None):
232 """@param element: the value for the L{element} attribute. 233 @param location: the value for the L{location} attribute. 234 """ 235 self.element = element 236 if (location is None) and isinstance(element, pyxb.utils.utility.Locatable_mixin): 237 location = element._location() 238 self.location = location 239 super(NonElementValidationError, self).__init__(element, location)
240
241 - def __str__ (self):
242 import pyxb.binding.basis 243 import xml.dom 244 value = '' 245 boundto = '' 246 location = '' 247 if isinstance(self.element, pyxb.binding.basis._TypeBinding_mixin): 248 eb = self.element._element() 249 boundto = '' 250 if eb is not None: 251 boundto = ' bound to %s' % (eb.name(),) 252 if isinstance(self.element, pyxb.binding.basis.simpleTypeDefinition): 253 value = self.element.xsdLiteral() 254 elif self.element._IsSimpleTypeContent(): 255 value = six.text_type(self.element.value()) 256 else: 257 value = 'Complex value' 258 elif isinstance(self.element, xml.dom.Node): 259 value = 'DOM node %s' % (self.element.nodeName,) 260 else: 261 value = '%s type %s' % (six.text_type(self.element), type(self.element)) 262 if self.location is not None: 263 location = ' at %s' % (self.location,) 264 return six.u('%s%s not permitted%s') % (value, boundto, location)
265
266 -class ElementValidationError (ValidationError):
267 """Raised when a validation requirement for an element is not satisfied.""" 268 pass
269
270 @six.python_2_unicode_compatible 271 -class AbstractElementError (ElementValidationError):
272 """Attempt to create an instance of an abstract element. 273 274 Raised when an element is created and the identified binding is 275 abstract. Such elements cannot be created directly; instead the 276 creation must derive from an instance of the abstract element's 277 substitution group. 278 279 Since members of the substitution group self-identify using the 280 C{substitutionGroup} attribute, there is no general way to find 281 the set of elements which would be acceptable in place of the 282 abstract element.""" 283 284 element = None 285 """The abstract L{pyxb.binding.basis.element} in question""" 286 287 value = None 288 """The value proposed for the L{element}. This is usually going 289 to be a C{xml.dom.Node} used in the attempt to create the element, 290 C{None} if the abstract element was invoked without a node, or 291 another type if 292 L{pyxb.binding.content.ElementDeclaration.toDOM} is 293 mis-used.""" 294
295 - def __init__ (self, element, location, value=None):
296 """@param element: the value for the L{element} attribute. 297 @param location: the value for the L{location} attribute. 298 @param value: the value for the L{value} attribute.""" 299 self.element = element 300 self.location = location 301 self.value = value 302 super(AbstractElementError, self).__init__(element, location, value)
303
304 - def __str__ (self):
305 return six.u('Cannot instantiate abstract element %s directly') % (self.element.name(),)
306
307 @six.python_2_unicode_compatible 308 -class ContentInNilInstanceError (ElementValidationError):
309 """Raised when an element that is marked to be nil is assigned content.""" 310 311 instance = None 312 """The binding instance which is xsi:nil""" 313 314 content = None 315 """The content that was to be assigned to the instance.""" 316
317 - def __init__ (self, instance, content, location=None):
318 """@param instance: the value for the L{instance} attribute. 319 @param content: the value for the L{content} attribute. 320 @param location: the value for the L{location} attribute. Default taken from C{instance} if possible.""" 321 322 self.instance = instance 323 self.content = content 324 if location is None: 325 location = self.instance._location() 326 self.location = location 327 super(ContentInNilInstanceError, self).__init__(instance, content, location)
328
329 - def __str__ (self):
330 from pyxb.namespace.builtin import XMLSchema_instance as XSI 331 return six.u('%s with %s=true cannot have content') % (self.instance._diagnosticName(), XSI.nil)
332
333 -class NoNillableSupportError (ElementValidationError):
334 """Raised when invoking L{_setIsNil<pyxb.binding.basis._TypeBinding_mixin._setIsNil>} on a type that does not support nillable.""" 335 336 instance = None 337 """The binding instance on which an inappropriate operation was invoked.""" 338
339 - def __init__ (self, instance, location=None):
340 """@param instance: the value for the L{instance} attribute. 341 @param location: the value for the L{location} attribute. Default taken from C{instance} if possible.""" 342 self.instance = instance 343 if location is None: 344 location = self.instance._location() 345 self.location = location 346 super(NoNillableSupportError, self).__init__(instance, location)
347
348 @six.python_2_unicode_compatible 349 -class ElementChangeError (ElementValidationError):
350 """Attempt to change an element that has a fixed value constraint.""" 351 352 element = None 353 """The L{pyxb.binding.basis.element} that has a fixed value.""" 354 355 value = None 356 """The value that was to be assigned to the element.""" 357
358 - def __init__ (self, element, value, location=None):
359 """@param element: the value for the L{element} attribute. 360 @param value: the value for the L{value} attribute. 361 @param location: the value for the L{location} attribute. Default taken from C{value} if possible.""" 362 363 import pyxb.utils.utility 364 self.element = element 365 self.value = value 366 if (location is None) and isinstance(value, pyxb.utils.utility.Locatable_mixin): 367 location = value._location() 368 self.location = location 369 super(ElementChangeError, self).__init__(element, value, location)
370
371 - def __str__ (self):
372 return six.u('Value %s for element %s incompatible with fixed content') % (self.value, self.element.name())
373
374 -class ComplexTypeValidationError (ValidationError):
375 """Raised when a validation requirement for a complex type is not satisfied.""" 376 pass
377
378 @six.python_2_unicode_compatible 379 -class AbstractInstantiationError (ComplexTypeValidationError):
380 """Attempt to create an instance of an abstract complex type. 381 382 These types are analogous to abstract base classes, and cannot be 383 created directly. A type should be used that extends the abstract 384 class. 385 386 When an incoming document is missing the xsi:type attribute which 387 redirects an element with an abstract type to the correct type, 388 the L{node} attribute is provided so the user can get a clue as to 389 where the problem occured. When this exception is a result of 390 constructor mis-use in Python code, the traceback will tell you 391 where the problem lies. 392 """ 393 394 type = None 395 """The abstract L{pyxb.binding.basis.complexTypeDefinition} subclass used.""" 396 397 node = None 398 """The L{xml.dom.Element} from which instantiation was attempted, if available.""" 399
400 - def __init__ (self, type, location, node):
401 """@param type: the value for the L{type} attribute. 402 @param location: the value for the L{location} attribute. 403 @param node: the value for the L{node} attribute.""" 404 self.type = type 405 self.location = location 406 self.node = node 407 super(AbstractInstantiationError, self).__init__(type, location, node)
408
409 - def __str__ (self):
410 # If the type is abstract, it has to have a name. 411 return six.u('Cannot instantiate abstract type %s directly') % (self.type._ExpandedName,)
412
413 @six.python_2_unicode_compatible 414 -class AttributeOnSimpleTypeError (ComplexTypeValidationError):
415 """Attempt made to set an attribute on an element with simple type. 416 417 Note that elements with complex type and simple content may have 418 attributes; elements with simple type must not.""" 419 420 instance = None 421 """The simple type binding instance on which no attributes exist.""" 422 423 tag = None 424 """The name of the proposed attribute.""" 425 426 value = None 427 """The value proposed to be assigned to the non-existent attribute.""" 428
429 - def __init__ (self, instance, tag, value, location=None):
430 """@param instance: the value for the L{instance} attribute. 431 @param tag: the value for the L{tag} attribute. 432 @param value: the value for the L{value} attribute. 433 @param location: the value for the L{location} attribute. Default taken from C{instance} if possible.""" 434 435 self.instance = instance 436 self.tag = tag 437 self.value = value 438 if location is None: 439 location = self.instance._location() 440 self.location = location 441 super(AttributeOnSimpleTypeError, self).__init__(instance, tag, value, location)
442
443 - def __str__ (self):
444 return six.u('Simple type %s cannot support attribute %s') % (self.instance._Name(), self.tag)
445
446 -class ContentValidationError (ComplexTypeValidationError):
447 """Violation of a complex type content model.""" 448 pass
449
450 @six.python_2_unicode_compatible 451 -class ContentNondeterminismExceededError (ContentValidationError):
452 """Content validation exceeded the allowed limits of nondeterminism.""" 453 454 instance = None 455 """The binding instance being validated.""" 456
457 - def __init__ (self, instance):
458 """@param instance: the value for the L{instance} attribute.""" 459 self.instance = instance 460 super(ContentNondeterminismExceededError, self).__init__(instance)
461
462 - def __str__ (self):
463 return six.u('Nondeterminism exceeded validating %s') % (self.instance._Name(),)
464
465 @six.python_2_unicode_compatible 466 -class SimpleContentAbsentError (ContentValidationError):
467 """An instance with simple content was not provided with a value.""" 468 469 instance = None 470 """The binding instance for which simple content is missing.""" 471
472 - def __init__ (self, instance, location):
473 """@param instance: the value for the L{instance} attribute. 474 @param location: the value for the L{location} attribute.""" 475 self.instance = instance 476 self.location = location 477 super(SimpleContentAbsentError, self).__init__(instance, location)
478
479 - def __str__ (self):
480 return six.u('Type %s requires content') % (self.instance._Name(),)
481
482 @six.python_2_unicode_compatible 483 -class ExtraSimpleContentError (ContentValidationError):
484 """A complex type with simple content was provided too much content.""" 485 486 instance = None 487 """The binding instance that already has simple content assigned.""" 488 489 value = None 490 """The proposed addition to that simple content.""" 491
492 - def __init__ (self, instance, value, location=None):
493 """@param instance: the value for the L{instance} attribute. 494 @param value: the value for the L{value} attribute. 495 @param location: the value for the L{location} attribute.""" 496 self.instance = instance 497 self.value = value 498 self.location = location 499 super(ExtraSimpleContentError, self).__init__(instance, value, location)
500
501 - def __str__ (self):
502 return six.u('Instance of %s already has simple content value assigned') % (self.instance._Name(),)
503
504 @six.python_2_unicode_compatible 505 -class NonPluralAppendError (ContentValidationError):
506 """Attempt to append to an element which does not accept multiple instances.""" 507 508 instance = None 509 """The binding instance containing the element""" 510 511 element_declaration = None 512 """The L{pyxb.binding.content.ElementDeclaration} contained in C{instance} that does not accept multiple instances""" 513 514 value = None 515 """The proposed addition to the element in the instance""" 516
517 - def __init__ (self, instance, element_declaration, value):
518 """@param instance: the value for the L{instance} attribute. 519 @param element_declaration: the value for the L{element_declaration} attribute. 520 @param value: the value for the L{value} attribute.""" 521 self.instance = instance 522 self.element_declaration = element_declaration 523 self.value = value 524 super(NonPluralAppendError, self).__init__(instance, element_declaration, value)
525
526 - def __str__ (self):
527 return six.u('Instance of %s cannot append to element %s') % (self.instance._Name(), self.element_declaration.name())
528
529 @six.python_2_unicode_compatible 530 -class MixedContentError (ContentValidationError):
531 """Non-element content added to a complex type instance that does not support mixed content.""" 532 533 instance = None 534 """The binding instance.""" 535 536 value = None 537 """The non-element content.""" 538
539 - def __init__ (self, instance, value, location=None):
540 """@param instance: the value for the L{instance} attribute. 541 @param value: the value for the L{value} attribute. 542 @param location: the value for the L{location} attribute.""" 543 self.instance = instance 544 self.value = value 545 self.location = location 546 super(MixedContentError, self).__init__(instance, value, location)
547
548 - def __str__ (self):
549 if self.location is not None: 550 return six.u('Invalid non-element content at %s') % (self.location,) 551 return six.u('Invalid non-element content')
552
553 @six.python_2_unicode_compatible 554 -class UnprocessedKeywordContentError (ContentValidationError):
555 """A complex type constructor was provided with keywords that could not be recognized.""" 556 557 instance = None 558 """The binding instance being constructed.""" 559 560 keywords = None 561 """The keywords that could not be recognized. These may have been 562 intended to be attributes or elements, but cannot be identified as 563 either.""" 564
565 - def __init__ (self, instance, keywords, location=None):
566 """@param instance: the value for the L{instance} attribute. 567 @param keywords: the value for the L{keywords} attribute. 568 @param location: the value for the L{location} attribute.""" 569 self.instance = instance 570 self.keywords = keywords 571 self.location = location 572 super(UnprocessedKeywordContentError, self).__init__(instance, keywords, location)
573
574 - def __str__ (self):
575 return six.u('Unprocessed keywords instantiating %s: %s') % (self.instance._Name(), ' '.join(six.iterkeys(self.keywords)))
576
577 -class IncrementalElementContentError (ContentValidationError):
578 """Element or element-like content could not be validly associated with an sub-element in the content model. 579 580 This exception occurs when content is added to an element during 581 incremental validation, such as when positional arguments are used 582 in a constructor or material is appended either explicitly or 583 through parsing a DOM instance.""" 584 585 instance = None 586 """The binding for which the L{value} could not be associated with an element.""" 587 588 automaton_configuration = None 589 """The L{pyxb.binding.content.AutomatonConfiguration} representing the current state of the L{instance} content.""" 590 591 value = None 592 """The value that could not be associated with allowable content.""" 593
594 - def __init__ (self, instance, automaton_configuration, value, location=None):
595 """@param instance: the value for the L{instance} attribute. 596 @param automaton_configuration: the value for the L{automaton_configuration} attribute. 597 @param value: the value for the L{value} attribute. 598 @param location: the value for the L{location} attribute.""" 599 self.instance = instance 600 self.automaton_configuration = automaton_configuration 601 self.value = value 602 self.location = location 603 super(IncrementalElementContentError, self).__init__(instance, automaton_configuration, value, location)
604
605 - def _valueDescription (self):
606 import xml.dom 607 if isinstance(self.value, pyxb.binding.basis._TypeBinding_mixin): 608 return self.value._diagnosticName() 609 if isinstance(self.value, xml.dom.Node): 610 return self.value.nodeName 611 return six.text_type(self.value)
612
613 @six.python_2_unicode_compatible 614 -class UnrecognizedContentError (IncrementalElementContentError):
615 """Element or element-like content could not be validly associated with an sub-element in the content model. 616 617 This exception occurs when content is added to an element during incremental validation.""" 618
619 - def __str__ (self):
620 value = self._valueDescription() 621 acceptable = self.automaton_configuration.acceptableContent() 622 if 0 == acceptable: 623 expect = 'no more content' 624 else: 625 import pyxb.binding.content 626 seen = set() 627 names = [] 628 for u in acceptable: 629 if isinstance(u, pyxb.binding.content.ElementUse): 630 n = six.text_type(u.elementBinding().name()) 631 else: 632 assert isinstance(u, pyxb.binding.content.WildcardUse) 633 n = 'xs:any' 634 if not (n in seen): 635 names.append(n) 636 seen.add(n) 637 expect = ' or '.join(names) 638 location = '' 639 if self.location is not None: 640 location = ' at %s' % (self.location,) 641 return six.u('Invalid content %s%s (expect %s)') % (value, location, expect)
642
643 - def details (self):
644 import pyxb.binding.basis 645 import pyxb.binding.content 646 i = self.instance 647 rv = [ ] 648 if i._element() is not None: 649 rv.append('The containing element %s is defined at %s.' % (i._element().name(), i._element().xsdLocation())) 650 rv.append('The containing element type %s is defined at %s' % (self.instance._Name(), six.text_type(self.instance._XSDLocation))) 651 if self.location is not None: 652 rv.append('The unrecognized content %s begins at %s' % (self._valueDescription(), self.location)) 653 else: 654 rv.append('The unrecognized content is %s' % (self._valueDescription(),)) 655 rv.append('The %s automaton %s in an accepting state.' % (self.instance._Name(), self.automaton_configuration.isAccepting() and "is" or "is not")) 656 if isinstance(self.instance, pyxb.binding.basis.complexTypeDefinition) and self.instance._IsMixed(): 657 rv.append('Character information content would be permitted.') 658 acceptable = self.automaton_configuration.acceptableContent() 659 if 0 == len(acceptable): 660 rv.append('No elements or wildcards would be accepted at this point.') 661 else: 662 rv.append('The following element and wildcard content would be accepted:') 663 rv2 = [] 664 for u in acceptable: 665 if isinstance(u, pyxb.binding.content.ElementUse): 666 rv2.append('An element %s per %s' % (u.elementBinding().name(), u.xsdLocation())) 667 else: 668 assert isinstance(u, pyxb.binding.content.WildcardUse) 669 rv2.append('A wildcard per %s' % (u.xsdLocation(),)) 670 rv.append('\t' + '\n\t'.join(rv2)) 671 return '\n'.join(rv)
672
673 -class BatchElementContentError (ContentValidationError):
674 """Element/wildcard content cannot be reconciled with the required content model. 675 676 This exception occurs in post-construction validation using a 677 fresh validating automaton.""" 678 679 instance = None 680 """The binding instance being constructed.""" 681 682 fac_configuration = None 683 """The L{pyxb.utils.fac.Configuration} representing the current state of the L{instance} automaton.""" 684 685 symbols = None 686 """The sequence of symbols that were accepted as content prior to the error.""" 687 688 symbol_set = None 689 """The leftovers from L{pyxb.binding.basis.complexTypeDefinition._symbolSet} that could not be reconciled with the content model.""" 690
691 - def __init__ (self, instance, fac_configuration, symbols, symbol_set):
692 """@param instance: the value for the L{instance} attribute. 693 @param fac_configuration: the value for the L{fac_configuration} attribute. 694 @param symbols: the value for the L{symbols} attribute. 695 @param symbol_set: the value for the L{symbol_set} attribute.""" 696 self.instance = instance 697 self.fac_configuration = fac_configuration 698 self.symbols = symbols 699 self.symbol_set = symbol_set 700 super(BatchElementContentError, self).__init__(instance, fac_configuration, symbols, symbol_set)
701
702 - def details (self):
703 import pyxb.binding.basis 704 import pyxb.binding.content 705 i = self.instance 706 rv = [ ] 707 if i._element() is not None: 708 rv.append('The containing element %s is defined at %s.' % (i._element().name(), i._element().xsdLocation())) 709 rv.append('The containing element type %s is defined at %s' % (self.instance._Name(), six.text_type(self.instance._XSDLocation))) 710 rv.append('The %s automaton %s in an accepting state.' % (self.instance._Name(), self.fac_configuration.isAccepting() and "is" or "is not")) 711 if self.symbols is None: 712 rv.append('Any accepted content has been stored in instance') 713 elif 0 == len(self.symbols): 714 rv.append('No content has been accepted') 715 else: 716 rv.append('The last accepted content was %s' % (self.symbols[-1].value._diagnosticName(),)) 717 if isinstance(self.instance, pyxb.binding.basis.complexTypeDefinition) and self.instance._IsMixed(): 718 rv.append('Character information content would be permitted.') 719 acceptable = self.fac_configuration.acceptableSymbols() 720 if 0 == len(acceptable): 721 rv.append('No elements or wildcards would be accepted at this point.') 722 else: 723 rv.append('The following element and wildcard content would be accepted:') 724 rv2 = [] 725 for u in acceptable: 726 if isinstance(u, pyxb.binding.content.ElementUse): 727 rv2.append('An element %s per %s' % (u.elementBinding().name(), u.xsdLocation())) 728 else: 729 assert isinstance(u, pyxb.binding.content.WildcardUse) 730 rv2.append('A wildcard per %s' % (u.xsdLocation(),)) 731 rv.append('\t' + '\n\t'.join(rv2)) 732 if (self.symbol_set is None) or (0 == len(self.symbol_set)): 733 rv.append('No content remains unconsumed') 734 else: 735 rv.append('The following content was not processed by the automaton:') 736 rv2 = [] 737 for (ed, syms) in six.iteritems(self.symbol_set): 738 if ed is None: 739 rv2.append('xs:any (%u instances)' % (len(syms),)) 740 else: 741 rv2.append('%s (%u instances)' % (ed.name(), len(syms))) 742 rv.append('\t' + '\n\t'.join(rv2)) 743 return '\n'.join(rv)
744
745 -class IncompleteElementContentError (BatchElementContentError):
746 """Validation of an instance failed to produce an accepting state. 747 748 This exception occurs in batch-mode validation.""" 749 pass
750
751 -class UnprocessedElementContentError (BatchElementContentError):
752 """Validation of an instance produced an accepting state but left element material unconsumed. 753 754 This exception occurs in batch-mode validation.""" 755 pass
756
757 -class InvalidPreferredElementContentError (BatchElementContentError):
758 """Use of a preferred element led to inability to generate a valid document""" 759 760 preferred_symbol = None 761 """The element symbol which was not accepted.""" 762
763 - def __init__ (self, instance, fac_configuration, symbols, symbol_set, preferred_symbol):
764 """@param instance: the value for the L{instance} attribute. 765 @param fac_configuration: the value for the L{fac_configuration} attribute. 766 @param symbols: the value for the L{symbols} attribute. 767 @param symbol_set: the value for the L{symbol_set} attribute. 768 @param preferred_symbol: the value for the L{preferred_symbol} attribute. 769 """ 770 self.instance = instance 771 self.fac_configuration = fac_configuration 772 self.symbols = symbols 773 self.symbol_set = symbol_set 774 self.preferred_symbol = preferred_symbol 775 # Bypass immediate parent so we preserve the last argument 776 super(BatchElementContentError, self).__init__(instance, fac_configuration, symbols, symbol_set, preferred_symbol)
777
778 @six.python_2_unicode_compatible 779 -class OrphanElementContentError (ContentValidationError):
780 """An element expected to be used in content is not present in the instance. 781 782 This exception occurs in batch-mode validation when 783 L{pyxb.ValidationConfig.contentInfluencesGeneration} applies, 784 L{pyxb.ValidationConfig.orphanElementInContent} is set to 785 L{pyxb.ValidationConfig.RAISE_EXCEPTION}, and the content list 786 includes an element that is not in the binding instance 787 content. 788 """ 789 790 instance = None 791 """The binding instance.""" 792 793 preferred = None 794 """An element value from the L{instance} L{content<pyxb.binding.basis.complexTypeDefinition.content>} list which was not found in the L{instance}.""" 795
796 - def __init__ (self, instance, preferred):
797 """@param instance: the value for the L{instance} attribute. 798 @param preferred: the value for the L{preferred} attribute. 799 """ 800 self.instance = instance 801 self.preferred = preferred 802 super(OrphanElementContentError, self).__init__(instance, preferred)
803
804 - def __str__ (self):
805 return six.u('Preferred content element not found in instance')
806
807 @six.python_2_unicode_compatible 808 -class SimpleTypeValueError (ValidationError):
809 """Raised when a simple type value does not satisfy its constraints.""" 810 type = None 811 """The L{pyxb.binding.basis.simpleTypeDefinition} that constrains values.""" 812 813 value = None 814 """The value that violates the constraints of L{type}. In some 815 cases this is a tuple of arguments passed to a constructor that 816 failed with a built-in exception likeC{ValueError} or 817 C{OverflowError}.""" 818
819 - def __init__ (self, type, value, location=None):
820 """@param type: the value for the L{type} attribute. 821 @param value: the value for the L{value} attribute. 822 @param location: the value for the L{location} attribute. Default taken from C{value} if possible.""" 823 import pyxb.utils.utility 824 self.type = type 825 self.value = value 826 if (location is None) and isinstance(value, pyxb.utils.utility.Locatable_mixin): 827 location = value._location() 828 self.location = location 829 super(SimpleTypeValueError, self).__init__(type, value, location)
830
831 - def __str__ (self):
832 import pyxb.binding.basis 833 if isinstance(self.value, pyxb.binding.basis._TypeBinding_mixin): 834 return six.u('Type %s cannot be created from %s: %s') % (self.type._Name(), self.value._Name(), self.value) 835 return six.u('Type %s cannot be created from: %s') % (self.type._Name(), self.value)
836
837 @six.python_2_unicode_compatible 838 -class SimpleListValueError (SimpleTypeValueError):
839 """Raised when a list simple type contains a member that does not satisfy its constraints. 840 841 In this case, L{type} is the type of the list, and value 842 C{type._ItemType} is the type for which the L{value} is 843 unacceptable.""" 844
845 - def __str__ (self):
846 return six.u('Member type %s of list type %s cannot accept %s') % (self.type._ItemType._Name(), self.type._Name(), self.value)
847
848 @six.python_2_unicode_compatible 849 -class SimpleUnionValueError (SimpleTypeValueError):
850 """Raised when a union simple type contains a member that does not satisfy its constraints. 851 852 In this case, L{type} is the type of the union, and the value 853 C{type._MemberTypes} is the set of types for which the value is 854 unacceptable. 855 856 The L{value} itself is the tuple of arguments passed to the 857 constructor for the union.""" 858
859 - def __str__ (self):
860 return six.u('No memberType of %s can be constructed from %s') % (self.type._Name(), self.value)
861
862 @six.python_2_unicode_compatible 863 -class SimpleFacetValueError (SimpleTypeValueError):
864 """Raised when a simple type value does not satisfy a facet constraint. 865 866 This extends L{SimpleTypeValueError} with the L{facet} field which 867 can be used to determine why the value is unacceptable.""" 868 869 type = None 870 """The L{pyxb.binding.basis.simpleTypeDefinition} that constrains values.""" 871 872 value = None 873 """The value that violates the constraints of L{type}. In some 874 cases this is a tuple of arguments passed to a constructor that 875 failed with a built-in exception likeC{ValueError} or 876 C{OverflowError}.""" 877 878 facet = None 879 """The specific facet that is violated by the value.""" 880
881 - def __init__ (self, type, value, facet, location=None):
882 """@param type: the value for the L{type} attribute. 883 @param value: the value for the L{value} attribute. 884 @param facet: the value for the L{facet} attribute. 885 @param location: the value for the L{location} attribute. Default taken from C{value} if possible.""" 886 import pyxb.utils.utility 887 888 self.type = type 889 self.value = value 890 self.facet = facet 891 if (location is None) and isinstance(value, pyxb.utils.utility.Locatable_mixin): 892 location = value._location() 893 self.location = location 894 # Bypass immediate parent 895 super(SimpleTypeValueError, self).__init__(type, value, facet)
896
897 - def __str__ (self):
898 return six.u('Type %s %s constraint violated by value %s') % (self.type._Name(), self.facet._Name, self.value)
899
900 -class SimplePluralValueError (SimpleTypeValueError):
901 """Raised when context requires a plural value. 902 903 Unlike L{SimpleListValueError}, in this case the plurality is 904 external to C{type}, for example when an element has simple 905 content and allows multiple occurrences.""" 906 pass
907
908 -class AttributeValidationError (ValidationError):
909 """Raised when an attribute requirement is not satisfied.""" 910 911 type = None 912 """The L{pyxb.binding.basis.complexTypeDefinition} subclass of the instance.""" 913 914 tag = None 915 """The name of the attribute.""" 916 917 instance = None 918 """The binding instance, if available.""" 919
920 - def __init__ (self, type, tag, instance=None, location=None):
921 """@param type: the value for the L{type} attribute. 922 @param tag: the value for the L{tag} attribute. 923 @param instance: the value for the L{instance} attribute. 924 @param location: the value for the L{location} attribute. Default taken from C{instance} if possible. 925 """ 926 import pyxb.utils.utility as utility 927 self.type = type 928 self.tag = tag 929 self.instance = instance 930 if (location is None) and isinstance(instance, utility.Locatable_mixin): 931 location = instance._location() 932 self.location = location 933 super(AttributeValidationError, self).__init__(type, tag, instance, location)
934
935 @six.python_2_unicode_compatible 936 -class UnrecognizedAttributeError (AttributeValidationError):
937 """Attempt to reference an attribute not sanctioned by content model."""
938 - def __str__ (self):
939 return six.u('Attempt to reference unrecognized attribute %s in type %s') % (self.tag, self.type)
940
941 @six.python_2_unicode_compatible 942 -class ProhibitedAttributeError (AttributeValidationError):
943 """Raised when an attribute that is prohibited is set or referenced in an element."""
944 - def __str__ (self):
945 return six.u('Attempt to reference prohibited attribute %s in type %s') % (self.tag, self.type)
946
947 @six.python_2_unicode_compatible 948 -class MissingAttributeError (AttributeValidationError):
949 """Raised when an attribute that is required is missing in an element."""
950 - def __str__ (self):
951 return six.u('Instance of %s lacks required attribute %s') % (self.type, self.tag)
952
953 @six.python_2_unicode_compatible 954 -class AttributeChangeError (AttributeValidationError):
955 """Attempt to change an attribute that has a fixed value constraint."""
956 - def __str__ (self):
957 return six.u('Cannot change fixed attribute %s in type %s') % (self.tag, self.type)
958
959 -class BindingError (PyXBException):
960 """Raised when the bindings are mis-used. 961 962 These are not validation errors, but rather structural errors. 963 For example, attempts to extract complex content from a type that 964 requires simple content, or vice versa. """
965
966 @six.python_2_unicode_compatible 967 -class NotSimpleContentError (BindingError):
968 """An operation that requires simple content was invoked on a 969 complex type instance that does not have simple content.""" 970 971 instance = None 972 """The binding instance which should have had simple content.""" 973
974 - def __init__ (self, instance):
975 """@param instance: the binding instance that was mis-used. 976 This will be available in the L{instance} attribute.""" 977 self.instance = instance 978 super(BindingError, self).__init__(instance)
979 pass 980
981 - def __str__ (self):
982 return six.u('type %s does not have simple content') % (self.instance._Name(),)
983
984 @six.python_2_unicode_compatible 985 -class NotComplexContentError (BindingError):
986 """An operation that requires a content model was invoked on a 987 complex type instance that has empty or simple content.""" 988 989 instance = None 990 """The binding instance which should have had a content model.""" 991
992 - def __init__ (self, instance):
993 """@param instance: the binding instance that was mis-used. 994 This will be available in the L{instance} attribute.""" 995 self.instance = instance 996 super(BindingError, self).__init__(instance)
997
998 - def __str__ (self):
999 return six.u('type %s has simple/empty content') % (self.instance._Name(),)
1000
1001 @six.python_2_unicode_compatible 1002 -class ReservedNameError (BindingError):
1003 """Reserved name set in binding instance.""" 1004 1005 instance = None 1006 """The binding instance.""" 1007 1008 name = None 1009 """The name that was caught being assigned""" 1010
1011 - def __init__ (self, instance, name):
1012 """@param instance: the value for the L{instance} attribute. 1013 p@param name: the value for the L{name} attribute.""" 1014 self.instance = instance 1015 self.name = name 1016 super(ReservedNameError, self).__init__(instance, name)
1017
1018 - def __str__ (self):
1019 return six.u('%s is a reserved name within %s') % (self.name, self.instance._Name())
1020
1021 -class PyXBError (Exception):
1022 """Base class for exceptions that indicate a problem that the user probably can't fix.""" 1023 pass
1024
1025 -class UsageError (PyXBError):
1026 """Raised when the code detects user violation of an API."""
1027
1028 -class LogicError (PyXBError):
1029 """Raised when the code detects an implementation problem."""
1030
1031 -class IncompleteImplementationError (LogicError):
1032 """Raised when required capability has not been implemented. 1033 1034 This is only used where it is reasonable to expect the capability 1035 to be present, such as a feature of XML schema that is not 1036 supported (e.g., the redefine directive)."""
1037