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