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

Source Code for Module pyxb.exceptions_

  1  # -*- coding: utf-8 -*- 
  2  # Copyright 2009-2012, 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 exceptions 
24 25 -class PyXBException (exceptions.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 exceptions.Exception.__init__(self, *args)
51
52 -class SchemaValidationError (PyXBException):
53 """Raised when the XML hierarchy does not appear to be valid for an XML schema.""" 54 pass
55
56 -class NamespaceError (PyXBException):
57 """Violation of some rule relevant to XML Namespaces"""
58 - def __init__ (self, namespace, *args, **kw):
59 PyXBException.__init__(self, *args, **kw) 60 self.__namespace = namespace
61
62 - def namespace (self): return self.__namespace
63
64 -class NamespaceArchiveError (PyXBException):
65 """Problem related to namespace archives""" 66 pass
67
68 -class SchemaUniquenessError (PyXBException):
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):
74 # Prior to 2.5, exceptions did not inherit from object, and 75 # super could not be used. 76 #super(SchemaUniquenessError, self).__init__(*args, **kw) 77 PyXBException.__init__(self, *args, **kw) 78 self.__namespace = namespace 79 self.__schemaLocation = schema_location 80 self.__existingSchema = existing_schema
81
82 - def namespace (self): return self.__namespace
83 - def schemaLocation (self): return self.__schemaLocation
84 - def existingSchema (self): return self.__existingSchema
85
86 -class BindingGenerationError (PyXBException):
87 """Raised when something goes wrong generating the binding classes""" 88 pass
89
90 -class NamespaceUniquenessError (NamespaceError):
91 """Raised when an attempt is made to record multiple objects of the same name in the same namespace category.""" 92 pass
93
94 -class NotInNamespaceError (PyXBException):
95 '''Raised when a name is referenced that is not defined in the appropriate namespace.''' 96 __namespace = None 97 __ncName = None
98
99 -class BadDocumentError (PyXBException):
100 """Raised when processing document content and an error is encountered.""" 101 pass
102
103 -class StructuralBadDocumentError (BadDocumentError):
104 """Raised when processing document and the content model is not satisfied.""" 105 @property
106 - def element_use (self):
107 """The L{pyxb.binding.content.ElementDeclaration} instance to which the content should conform, if available.""" 108 return self.__elementUse
109 110 @property
111 - def container (self):
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
120 - def __init__ (self, *args, **kw):
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
141 -class UnrecognizedDOMRootNodeError (StructuralBadDocumentError):
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
147 - def __get_node_name (self):
148 """The QName of the L{node} as a L{pyxb.namespace.ExpandedName}""" 149 import pyxb.namespace 150 return pyxb.namespace.ExpandedName(self.node.namespaceURI, self.node.localName)
151 node_name = property(__get_node_name) 152
153 - def __init__ (self, node):
154 """@param node: the value for the L{node} attribute.""" 155 self.node = node 156 super(UnrecognizedDOMRootNodeError, self).__init__(node)
157
158 -class ValidationError (PyXBException):
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
173 - def details (self):
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
185 -class ElementValidationError (ValidationError):
186 """Raised when a validation requirement for an element is not satisfied.""" 187 pass
188
189 -class AbstractElementError (ElementValidationError):
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):
214 """@param element: the value for the L{element} attribute. 215 @param location: the value for the L{location} attribute. 216 @param value: the value for the L{value} attribute.""" 217 self.element = element 218 self.location = location 219 self.value = value 220 super(AbstractElementError, self).__init__(element, location, value)
221
222 - def __str__ (self):
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
250 -class NoNillableSupportError (ElementValidationError):
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):
257 """@param instance: the value for the L{instance} attribute. 258 @param location: the value for the L{location} attribute. Default taken from C{instance} if possible.""" 259 self.instance = instance 260 if location is None: 261 location = self.instance._location() 262 self.location = location 263 super(NoNillableSupportError, self).__init__(instance, location)
264
265 -class ElementChangeError (ElementValidationError):
266 """Attempt to change an element that has a fixed value constraint.""" 267 268 element = None 269 """The L{pyxb.binding.basis.element} that has a fixed value.""" 270 271 value = None 272 """The value that was to be assigned to the element.""" 273
274 - def __init__ (self, element, value, location=None):
275 """@param element: the value for the L{element} attribute. 276 @param value: the value for the L{value} attribute. 277 @param location: the value for the L{location} attribute. Default taken from C{value} if possible.""" 278 279 import pyxb.utils.utility 280 self.element = element 281 self.value = value 282 if (location is None) and isinstance(value, pyxb.utils.utility.Locatable_mixin): 283 location = value._location() 284 self.location = location 285 super(ElementChangeError, self).__init__(element, value, location)
286
287 - def __str__ (self):
288 return 'Element %s has fixed content %s' % (self.element.name(), self.value)
289
290 -class ComplexTypeValidationError (ValidationError):
291 """Raised when a validation requirement for a complex type is not satisfied.""" 292 pass
293
294 -class AbstractInstantiationError (ComplexTypeValidationError):
295 """Attempt to create an instance of an abstract complex type. 296 297 These types are analogous to abstract base classes, and cannot be 298 created directly. A type should be used that extends the abstract 299 class. 300 301 When an incoming document is missing the xsi:type attribute which 302 redirects an element with an abstract type to the correct type, 303 the L{node} attribute is provided so the user can get a clue as to 304 where the problem occured. When this exception is a result of 305 constructor mis-use in Python code, the traceback will tell you 306 where the problem lies. 307 """ 308 309 type = None 310 """The abstract L{pyxb.binding.basis.complexTypeDefinition} subclass used.""" 311 312 node = None 313 """The L{xml.dom.Element} from which instantiation was attempted, if available.""" 314
315 - def __init__ (self, type, location, node):
316 """@param type: the value for the L{type} attribute. 317 @param location: the value for the L{location} attribute. 318 @param node: the value for the L{node} attribute.""" 319 self.type = type 320 self.location = location 321 self.node = node 322 super(AbstractInstantiationError, self).__init__(type, location, node)
323
324 - def __str__ (self):
325 # If the type is abstract, it has to have a name. 326 return 'Cannot instantiate abstract type %s directly' % (self.type._ExpandedName,)
327
328 -class AttributeOnSimpleTypeError (ComplexTypeValidationError):
329 """Attempt made to set an attribute on an element with simple type. 330 331 Note that elements with complex type and simple content may have 332 attributes; elements with simple type must not.""" 333 334 instance = None 335 """The simple type binding instance on which no attributes exist.""" 336 337 tag = None 338 """The name of the proposed attribute.""" 339 340 value = None 341 """The value proposed to be assigned to the non-existent attribute.""" 342
343 - def __init__ (self, instance, tag, value, location=None):
344 """@param instance: the value for the L{instance} attribute. 345 @param tag: the value for the L{tag} attribute. 346 @param value: the value for the L{value} attribute. 347 @param location: the value for the L{location} attribute. Default taken from C{instance} if possible.""" 348 349 self.instance = instance 350 self.tag = tag 351 self.value = value 352 if location is None: 353 location = self.instance._location() 354 self.location = location 355 super(AttributeOnSimpleTypeError, self).__init__(instance, tag, value, location)
356
357 - def __str__ (self):
358 return 'Simple type %s cannot support attribute %s' % (self.instance._Name(), self.tag)
359
360 -class ContentValidationError (ComplexTypeValidationError):
361 """Violation of a complex type content model.""" 362 pass
363
364 -class SimpleContentAbsentError (ContentValidationError):
365 """An instance with simple content was not provided with a value.""" 366 367 instance = None 368 """The binding instance for which simple content is missing.""" 369
370 - def __init__ (self, instance, location):
371 """@param instance: the value for the L{instance} attribute. 372 @param location: the value for the L{location} attribute.""" 373 self.instance = instance 374 self.location = location 375 super(SimpleContentAbsentError, self).__init__(instance, location)
376
377 - def __str__ (self):
378 return 'Type %s requires content' % (self.instance._Name(),)
379
380 -class ExtraSimpleContentError (ContentValidationError):
381 """A complex type with simple content was provided too much content.""" 382 383 instance = None 384 """The binding instance that already has simple content assigned.""" 385 386 value = None 387 """The proposed addition to that simple content.""" 388
389 - def __init__ (self, instance, value, location=None):
390 """@param instance: the value for the L{instance} attribute. 391 @param value: the value for the L{value} attribute. 392 @param location: the value for the L{location} attribute.""" 393 self.instance = instance 394 self.value = value 395 self.location = location 396 super(ExtraSimpleContentError, self).__init__(instance, value, location)
397
398 - def __str__ (self):
399 return 'Instance of %s already has simple content value assigned' % (self.instance._Name(),)
400
401 -class MixedContentError (ContentValidationError):
402 """Non-element content added to a complex type instance that does not support mixed content.""" 403 404 instance = None 405 """The binding instance.""" 406 407 value = None 408 """The non-element content.""" 409
410 - def __init__ (self, instance, value, location=None):
411 """@param instance: the value for the L{instance} attribute. 412 @param value: the value for the L{value} attribute. 413 @param location: the value for the L{location} attribute.""" 414 self.instance = instance 415 self.value = value 416 self.location = location 417 super(MixedContentError, self).__init__(instance, value, location)
418
419 - def __str__ (self):
420 if self.location is not None: 421 return 'Invalid non-element content at %s' % (self.location,) 422 return 'Invalid non-element content'
423
424 -class UnprocessedKeywordContentError (ContentValidationError):
425 """A complex type constructor was provided with keywords that could not be recognized.""" 426 427 instance = None 428 """The binding instance being constructed.""" 429 430 keywords = None 431 """The keywords that could not be recognized. These may have been 432 intended to be attributes or elements, but cannot be identified as 433 either.""" 434
435 - def __init__ (self, instance, keywords, location=None):
436 """@param instance: the value for the L{instance} attribute. 437 @param keywords: the value for the L{keywords} attribute. 438 @param location: the value for the L{location} attribute.""" 439 self.instance = instance 440 self.keywords = keywords 441 self.location = location 442 super(UnprocessedKeywordContentError, self).__init__(instance, keywords, location)
443
444 - def __str__ (self):
445 return 'Unprocessed keywords instantiating %s: %s' % (self.instance._Name(), ' '.join(self.keywords.keys()))
446
447 -class IncrementalElementContentError (ContentValidationError):
448 """Element or element-like content could not be validly associated with an sub-element in the content model. 449 450 This exception occurs when content is added to an element during 451 incremental validation, such as when positional arguments are used 452 in a constructor or material is appended either explicitly or 453 through parsing a DOM instance.""" 454 455 instance = None 456 """The binding for which the L{value} could not be associated with an element.""" 457 458 automaton_configuration = None 459 """The L{pyxb.binding.content.AutomatonConfiguration} representing the current state of the L{instance} content.""" 460 461 value = None 462 """The value that could not be associated with allowable content.""" 463
464 - def __init__ (self, instance, automaton_configuration, value, location=None):
465 """@param instance: the value for the L{instance} attribute. 466 @param automaton_configuration: the value for the L{automaton_configuration} attribute. 467 @param value: the value for the L{value} attribute. 468 @param location: the value for the L{location} attribute.""" 469 self.instance = instance 470 self.automaton_configuration = automaton_configuration 471 self.value = value 472 self.location = location 473 super(IncrementalElementContentError, self).__init__(instance, automaton_configuration, value, location)
474
475 -class UnrecognizedContentError (IncrementalElementContentError):
476 """Element or element-like content could not be validly associated with an sub-element in the content model. 477 478 This exception occurs when content is added to an element during incremental validation.""" 479
480 - def __str__ (self):
481 value = self.value 482 try: 483 value = str(self.value._element().name()) 484 except: 485 pass 486 acceptable = self.automaton_configuration.acceptableContent() 487 if 0 == acceptable: 488 expect = 'no more content' 489 else: 490 import pyxb.binding.content 491 seen = set() 492 names = [] 493 for u in acceptable: 494 if isinstance(u, pyxb.binding.content.ElementUse): 495 n = str(u.elementBinding().name()) 496 else: 497 assert isinstance(u, pyxb.binding.content.WildcardUse) 498 n = 'xs:any' 499 if not (n in seen): 500 names.append(n) 501 seen.add(n) 502 expect = ' or '.join(names) 503 location = '' 504 if self.location is not None: 505 location = ' at %s' % (self.location,) 506 return 'Invalid content %s%s (expect %s)' % (value, location, expect)
507
508 - def details (self):
509 import pyxb.binding.basis 510 import pyxb.binding.content 511 i = self.instance 512 rv = [ ] 513 if i._element() is not None: 514 rv.append('The containing element %s is defined at %s.' % (i._element().name(), i._element().xsdLocation())) 515 rv.append('The containing element type %s is defined at %s' % (self.instance._Name(), str(self.instance._XSDLocation))) 516 if self.location is not None: 517 rv.append('The unrecognized content %s begins at %s' % (self.value._diagnosticName(), self.location)) 518 else: 519 rv.append('The unrecognized content is %s' % (self.value._diagnosticName(),)) 520 ty = type(self.instance) 521 rv.append('The %s automaton %s in an accepting state.' % (self.instance._Name(), self.automaton_configuration.isAccepting() and "is" or "is not")) 522 if isinstance(self.instance, pyxb.binding.basis.complexTypeDefinition) and self.instance._IsMixed(): 523 rv.append('Character information content would be permitted.') 524 acceptable = self.automaton_configuration.acceptableContent() 525 if 0 == len(acceptable): 526 rv.append('No elements or wildcards would be accepted at this point.') 527 else: 528 rv.append('The following element and wildcard content would be accepted:') 529 rv2 = [] 530 for u in acceptable: 531 if isinstance(u, pyxb.binding.content.ElementUse): 532 rv2.append('An element %s per %s' % (u.elementBinding().name(), u.xsdLocation())) 533 else: 534 assert isinstance(u, pyxb.binding.content.WildcardUse) 535 rv2.append('A wildcard per %s' % (u.xsdLocation(),)) 536 rv.append('\t' + '\n\t'.join(rv2)) 537 return '\n'.join(rv)
538
539 -class BatchElementContentError (ContentValidationError):
540 """Element/wildcard content cannot be reconciled with the required content model. 541 542 This exception occurs in post-construction validation using a 543 fresh validating automaton.""" 544 545 instance = None 546 """The binding instance being constructed.""" 547 548 fac_configuration = None 549 """The L{pyxb.utils.fac.Configuration} representing the current state of the L{instance} automaton.""" 550 551 symbols = None 552 """The sequence of symbols that were accepted as content prior to the error.""" 553 554 symbol_set = None 555 """The leftovers from L{pyxb.binding.basis.complexTypeDefinition._symbolSet} that could not be reconciled with the content model.""" 556
557 - def __init__ (self, instance, fac_configuration, symbols, symbol_set):
558 """@param instance: the value for the L{instance} attribute. 559 @param fac_configuration: the value for the L{fac_configuration} attribute. 560 @param symbols: the value for the L{symbols} attribute. 561 @param symbol_set: the value for the L{symbol_set} attribute.""" 562 self.instance = instance 563 self.fac_configuration = fac_configuration 564 self.symbols = symbols 565 self.symbol_set = symbol_set 566 super(BatchElementContentError, self).__init__(instance, fac_configuration, symbols, symbol_set)
567
568 - def details (self):
569 import pyxb.binding.basis 570 import pyxb.binding.content 571 i = self.instance 572 rv = [ ] 573 if i._element() is not None: 574 rv.append('The containing element %s is defined at %s.' % (i._element().name(), i._element().xsdLocation())) 575 rv.append('The containing element type %s is defined at %s' % (self.instance._Name(), str(self.instance._XSDLocation))) 576 ty = type(self.instance) 577 rv.append('The %s automaton %s in an accepting state.' % (self.instance._Name(), self.fac_configuration.isAccepting() and "is" or "is not")) 578 if self.symbols is None: 579 rv.append('Any accepted content has been stored in instance') 580 elif 0 == len(self.symbols): 581 rv.append('No content has been accepted') 582 else: 583 rv.append('The last accepted content was %s' % (self.symbols[-1].value._diagnosticName(),)) 584 if isinstance(self.instance, pyxb.binding.basis.complexTypeDefinition) and self.instance._IsMixed(): 585 rv.append('Character information content would be permitted.') 586 acceptable = self.fac_configuration.acceptableSymbols() 587 if 0 == len(acceptable): 588 rv.append('No elements or wildcards would be accepted at this point.') 589 else: 590 rv.append('The following element and wildcard content would be accepted:') 591 rv2 = [] 592 for u in acceptable: 593 if isinstance(u, pyxb.binding.content.ElementUse): 594 rv2.append('An element %s per %s' % (u.elementBinding().name(), u.xsdLocation())) 595 else: 596 assert isinstance(u, pyxb.binding.content.WildcardUse) 597 rv2.append('A wildcard per %s' % (u.xsdLocation(),)) 598 rv.append('\t' + '\n\t'.join(rv2)) 599 if (self.symbol_set is None) or (0 == len(self.symbol_set)): 600 rv.append('No content remains unconsumed') 601 else: 602 rv.append('The following content was not processed by the automaton:') 603 rv2 = [] 604 for (ed, syms) in self.symbol_set.iteritems(): 605 if ed is None: 606 rv2.append('xs:any (%u instances)' % (len(syms),)) 607 else: 608 rv2.append('%s (%u instances)' % (ed.name(), len(syms))) 609 rv.append('\t' + '\n\t'.join(rv2)) 610 return '\n'.join(rv)
611
612 -class IncompleteElementContentError (BatchElementContentError):
613 """Validation of an instance failed to produce an accepting state. 614 615 This exception occurs in batch-mode validation.""" 616 pass
617
618 -class UnprocessedElementContentError (BatchElementContentError):
619 """Validation of an instance produced an accepting state but left element material unconsumed. 620 621 This exception occurs in batch-mode validation.""" 622 pass
623
624 -class InvalidPreferredElementContentError (BatchElementContentError):
625 """Use of a preferred element led to inability to generate a valid document""" 626 627 preferred_symbol = None 628 """The element symbol which was not accepted.""" 629
630 - def __init__ (self, instance, fac_configuration, symbols, symbol_set, preferred_symbol):
631 """@param instance: the value for the L{instance} attribute. 632 @param fac_configuration: the value for the L{fac_configuration} attribute. 633 @param symbols: the value for the L{symbols} attribute. 634 @param symbol_set: the value for the L{symbol_set} attribute. 635 @param preferred_symbol: the value for the L{preferred_symbol} attribute. 636 """ 637 self.instance = instance 638 self.fac_configuration = fac_configuration 639 self.symbols = symbols 640 self.symbol_set = symbol_set 641 self.preferred_symbol = preferred_symbol 642 # Bypass immediate parent so we preserve the last argument 643 super(BatchElementContentError, self).__init__(instance, fac_configuration, symbols, symbol_set, preferred_content)
644
645 646 -class OrphanElementContentError (ContentValidationError):
647 """An element expected to be used in content is not present in the instance. 648 649 This exception occurs in batch-mode validation when 650 L{pyxb.ValidationConfig.contentInfluencesGeneration} applies, 651 L{pyxb.ValidationConfig.orphanElementInContent} is set to 652 L{pyxb.ValidationConfig.RAISE_EXCEPTION}, and the content list 653 includes an element that is not in the binding instance 654 content. 655 """ 656 657 instance = None 658 """The binding instance.""" 659 660 preferred = None 661 """An element value from the L{instance} L{content<pyxb.binding.basis.complexTypeDefinition.content>} list which was not found in the L{instance}.""" 662
663 - def __init__ (self, instance, preferred):
664 """@param instance: the value for the L{instance} attribute. 665 @param preferred: the value for the L{preferred} attribute. 666 """ 667 self.instance = instance 668 self.preferred = preferred 669 super(OrphanElementContentError, self).__init__(instance, preferred)
670
671 - def __str__ (self):
672 return 'Preferred content element not found in instance'
673
674 -class SimpleTypeValueError (ValidationError):
675 """Raised when a simple type value does not satisfy its constraints.""" 676 type = None 677 """The L{pyxb.binding.basis.simpleTypeDefinition} that constrains values.""" 678 679 value = None 680 """The value that violates the constraints of L{type}. In some 681 cases this is a tuple of arguments passed to a constructor that 682 failed with a built-in exception likeC{ValueError} or 683 C{OverflowError}.""" 684
685 - def __init__ (self, type, value, location=None):
686 """@param type: the value for the L{type} attribute. 687 @param value: the value for the L{value} attribute. 688 @param location: the value for the L{location} attribute. Default taken from C{value} if possible.""" 689 import pyxb.utils.utility 690 self.type = type 691 self.value = value 692 if (location is None) and isinstance(value, pyxb.utils.utility.Locatable_mixin): 693 location = value._location() 694 self.location = location 695 super(SimpleTypeValueError, self).__init__(type, value, location)
696
697 - def __str__ (self):
698 import pyxb.binding.basis 699 if isinstance(self.value, pyxb.binding.basis._TypeBinding_mixin): 700 return 'Type %s cannot be created from %s: %s' % (self.type._Name(), self.value._Name(), self.value) 701 return 'Type %s cannot be created from: %s' % (self.type._Name(), self.value)
702
703 -class SimpleListValueError (SimpleTypeValueError):
704 """Raised when a list simple type contains a member that does not satisfy its constraints. 705 706 In this case, L{type} is the type of the list, and value 707 C{type._ItemType} is the type for which the L{value} is 708 unacceptable.""" 709
710 - def __str__ (self):
711 return 'Member type %s of list type %s cannot accept %s' % (self.type._ItemType._Name(), self.type._Name(), self.value)
712
713 -class SimpleUnionValueError (SimpleTypeValueError):
714 """Raised when a union simple type contains a member that does not satisfy its constraints. 715 716 In this case, L{type} is the type of the union, and the value 717 C{type._MemberTypes} is the set of types for which the value is 718 unacceptable. 719 720 The L{value} itself is the tuple of arguments passed to the 721 constructor for the union.""" 722
723 - def __str__ (self):
724 return 'No memberType of %s can be constructed from %s' % (self.type._Name(), self.value)
725
726 -class SimpleFacetValueError (SimpleTypeValueError):
727 """Raised when a simple type value does not satisfy a facet constraint. 728 729 This extends L{SimpleTypeValueError} with the L{facet} field which 730 can be used to determine why the value is unacceptable.""" 731 732 type = None 733 """The L{pyxb.binding.basis.simpleTypeDefinition} that constrains values.""" 734 735 value = None 736 """The value that violates the constraints of L{type}. In some 737 cases this is a tuple of arguments passed to a constructor that 738 failed with a built-in exception likeC{ValueError} or 739 C{OverflowError}.""" 740 741 facet = None 742 """The specific facet that is violated by the value.""" 743
744 - def __init__ (self, type, value, facet, location=None):
745 """@param type: the value for the L{type} attribute. 746 @param value: the value for the L{value} attribute. 747 @param facet: the value for the L{facet} attribute. 748 @param location: the value for the L{location} attribute. Default taken from C{value} if possible.""" 749 import pyxb.utils.utility 750 751 self.type = type 752 self.value = value 753 self.facet = facet 754 if (location is None) and isinstance(value, pyxb.utils.utility.Locatable_mixin): 755 location = value._location() 756 self.location = location 757 # Bypass immediate parent 758 super(SimpleTypeValueError, self).__init__(type, value, facet)
759
760 - def __str__ (self):
761 return 'Type %s %s constraint violated by value %s' % (self.type._Name(), self.facet._Name, self.value)
762
763 -class SimplePluralValueError (SimpleTypeValueError):
764 """Raised when context requires a plural value. 765 766 Unlike L{SimpleListValueError}, in this case the plurality is 767 external to C{type}, for example when an element has simple 768 content and allows multiple occurrences.""" 769 pass
770
771 -class AttributeValidationError (ValidationError):
772 """Raised when an attribute requirement is not satisfied.""" 773 774 type = None 775 """The L{pyxb.binding.basis.complexTypeDefinition} subclass of the instance.""" 776 777 tag = None 778 """The name of the attribute.""" 779 780 instance = None 781 """The binding instance, if available.""" 782
783 - def __init__ (self, type, tag, instance=None, location=None):
784 """@param type: the value for the L{type} attribute. 785 @param tag: the value for the L{tag} attribute. 786 @param instance: the value for the L{instance} attribute. 787 @param location: the value for the L{location} attribute. Default taken from C{instance} if possible. 788 """ 789 import pyxb.utils.utility as utility 790 self.type = type 791 self.tag = tag 792 self.instance = instance 793 if (location is None) and isinstance(instance, utility.Locatable_mixin): 794 location = instance._location() 795 self.location = location 796 super(AttributeValidationError, self).__init__(type, tag, instance, location)
797
798 -class UnrecognizedAttributeError (AttributeValidationError):
799 """Attempt to reference an attribute not sanctioned by content model.""" 800 pass
801
802 -class ProhibitedAttributeError (AttributeValidationError):
803 """Raised when an attribute that is prohibited is set or referenced in an element."""
804 - def __str__ (self):
805 return 'Attempt to reference prohibited attribute %s in type %s' % (self.tag, self.type)
806
807 -class MissingAttributeError (AttributeValidationError):
808 """Raised when an attribute that is required is missing in an element."""
809 - def __str__ (self):
810 return 'Instance of %s lacks required attribute %s' % (self.type, self.tag)
811
812 -class AttributeChangeError (AttributeValidationError):
813 """Attempt to change an attribute that has a fixed value constraint."""
814 - def __str__ (self):
815 return 'Cannot change fixed attribute %s in type %s' % (self.tag, self.type)
816
817 -class BindingError (PyXBException):
818 """Raised when the bindings are mis-used. 819 820 These are not validation errors, but rather structural errors. 821 For example, attempts to extract complex content from a type that 822 requires simple content, or vice versa. """
823
824 -class NotSimpleContentError (BindingError):
825 """An operation that requires simple content was invoked on a 826 complex type instance that does not have simple content.""" 827 828 instance = None 829 """The binding instance which should have had simple content.""" 830
831 - def __init__ (self, instance):
832 """@param instance: the binding instance that was mis-used. 833 This will be available in the L{instance} attribute.""" 834 self.instance = instance 835 super(BindingError, self).__init__(instance)
836 pass 837
838 - def __str__ (self):
839 return 'type %s does not have simple content' % (self.instance._Name(),)
840
841 -class NotComplexContentError (BindingError):
842 """An operation that requires a content model was invoked on a 843 complex type instance that has empty or simple content.""" 844 845 instance = None 846 """The binding instance which should have had a content model.""" 847
848 - def __init__ (self, instance):
849 """@param instance: the binding instance that was mis-used. 850 This will be available in the L{instance} attribute.""" 851 self.instance = instance 852 super(BindingError, self).__init__(instance)
853
854 - def __str__ (self):
855 return 'type %s has simple/empty content' % (self.instance._Name(),)
856
857 -class ReservedNameError (BindingError):
858 """Reserved name set in binding instance.""" 859 860 instance = None 861 """The binding instance.""" 862 863 name = None 864 """The name that was caught being assigned""" 865
866 - def __init__ (self, instance, name):
867 """@param instance: the value for the L{instance} attribute. 868 p@param name: the value for the L{name} attribute.""" 869 self.instance = instance 870 self.name = name 871 super(ReservedNameError, self).__init__(instance, name)
872
873 - def __str__ (self):
874 return '%s is a reserved name within %s' % (self.name, self.instance._Name())
875
876 -class PyXBError (exceptions.Exception):
877 """Base class for exceptions that indicate a problem that the user probably can't fix.""" 878 pass
879
880 -class UsageError (PyXBError):
881 """Raised when the code detects user violation of an API."""
882
883 -class LogicError (PyXBError):
884 """Raised when the code detects an implementation problem."""
885
886 -class IncompleteImplementationError (LogicError):
887 """Raised when required capability has not been implemented. 888 889 This is only used where it is reasonable to expect the capability 890 to be present, such as a feature of XML schema that is not 891 supported (e.g., the redefine directive)."""
892