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 ComplexTypeValidationError (ValidationError):
266 """Raised when a validation requirement for a complex type is not satisfied.""" 267 pass
268
269 -class AbstractInstantiationError (ComplexTypeValidationError):
270 """Attempt to create an instance of an abstract complex type. 271 272 These types are analogous to abstract base classes, and cannot be 273 created directly. A type should be used that extends the abstract 274 class. 275 276 When an incoming document is missing the xsi:type attribute which 277 redirects an element with an abstract type to the correct type, 278 the L{node} attribute is provided so the user can get a clue as to 279 where the problem occured. When this exception is a result of 280 constructor mis-use in Python code, the traceback will tell you 281 where the problem lies. 282 """ 283 284 type = None 285 """The abstract L{pyxb.binding.basis.complexTypeDefinition} subclass used.""" 286 287 node = None 288 """The L{xml.dom.Element} from which instantiation was attempted, if available.""" 289
290 - def __init__ (self, type, location, node):
291 """@param type: the value for the L{type} attribute. 292 @param location: the value for the L{location} attribute. 293 @param node: the value for the L{node} attribute.""" 294 self.type = type 295 self.location = location 296 self.node = node 297 super(AbstractInstantiationError, self).__init__(type, location, node)
298
299 - def __str__ (self):
300 # If the type is abstract, it has to have a name. 301 return 'Cannot instantiate abstract type %s directly' % (self.type._ExpandedName,)
302
303 -class AttributeOnSimpleTypeError (ComplexTypeValidationError):
304 """Attempt made to set an attribute on an element with simple type. 305 306 Note that elements with complex type and simple content may have 307 attributes; elements with simple type must not.""" 308 309 instance = None 310 """The simple type binding instance on which no attributes exist.""" 311 312 tag = None 313 """The name of the proposed attribute.""" 314 315 value = None 316 """The value proposed to be assigned to the non-existent attribute.""" 317
318 - def __init__ (self, instance, tag, value, location=None):
319 """@param instance: the value for the L{instance} attribute. 320 @param tag: the value for the L{tag} attribute. 321 @param value: the value for the L{value} attribute. 322 @param location: the value for the L{location} attribute. Default taken from C{instance} if possible.""" 323 324 self.instance = instance 325 self.tag = tag 326 self.value = value 327 if location is None: 328 location = self.instance._location() 329 self.location = location 330 super(AttributeOnSimpleTypeError, self).__init__(instance, tag, value, location)
331
332 - def __str__ (self):
333 return 'Simple type %s cannot support attribute %s' % (self.instance._Name(), self.tag)
334
335 -class ContentValidationError (ComplexTypeValidationError):
336 """Violation of a complex type content model.""" 337 pass
338
339 -class SimpleContentAbsentError (ContentValidationError):
340 """An instance with simple content was not provided with a value.""" 341 342 instance = None 343 """The binding instance for which simple content is missing.""" 344
345 - def __init__ (self, instance, location):
346 """@param instance: the value for the L{instance} attribute. 347 @param location: the value for the L{location} attribute.""" 348 self.instance = instance 349 self.location = location 350 super(SimpleContentAbsentError, self).__init__(instance, location)
351
352 - def __str__ (self):
353 return 'Type %s requires content' % (self.instance._Name(),)
354
355 -class ExtraSimpleContentError (ContentValidationError):
356 """A complex type with simple content was provided too much content.""" 357 358 instance = None 359 """The binding instance that already has simple content assigned.""" 360 361 value = None 362 """The proposed addition to that simple content.""" 363
364 - def __init__ (self, instance, value, location=None):
365 """@param instance: the value for the L{instance} attribute. 366 @param value: the value for the L{value} attribute. 367 @param location: the value for the L{location} attribute.""" 368 self.instance = instance 369 self.value = value 370 self.location = location 371 super(ExtraSimpleContentError, self).__init__(instance, value, location)
372
373 - def __str__ (self):
374 return 'Instance of %s already has simple content value assigned' % (self.instance._Name(),)
375
376 -class MixedContentError (ContentValidationError):
377 """Non-element content added to a complex type instance that does not support mixed content.""" 378 379 instance = None 380 """The binding instance.""" 381 382 value = None 383 """The non-element content.""" 384
385 - def __init__ (self, instance, value, location=None):
386 """@param instance: the value for the L{instance} attribute. 387 @param value: the value for the L{value} attribute. 388 @param location: the value for the L{location} attribute.""" 389 self.instance = instance 390 self.value = value 391 self.location = location 392 super(MixedContentError, self).__init__(instance, value, location)
393
394 - def __str__ (self):
395 if self.location is not None: 396 return 'Invalid non-element content at %s' % (self.location,) 397 return 'Invalid non-element content'
398
399 -class UnprocessedKeywordContentError (ContentValidationError):
400 """A complex type constructor was provided with keywords that could not be recognized.""" 401 402 instance = None 403 """The binding instance being constructed.""" 404 405 keywords = None 406 """The keywords that could not be recognized. These may have been 407 intended to be attributes or elements, but cannot be identified as 408 either.""" 409
410 - def __init__ (self, instance, keywords, location=None):
411 """@param instance: the value for the L{instance} attribute. 412 @param keywords: the value for the L{keywords} attribute. 413 @param location: the value for the L{location} attribute.""" 414 self.instance = instance 415 self.keywords = keywords 416 self.location = location 417 super(UnprocessedKeywordContentError, self).__init__(instance, keywords, location)
418
419 - def __str__ (self):
420 return 'Unprocessed keywords instantiating %s: %s' % (self.instance._Name(), ' '.join(self.keywords.keys()))
421
422 -class IncrementalElementContentError (ContentValidationError):
423 """Element or element-like content could not be validly associated with an sub-element in the content model. 424 425 This exception occurs when content is added to an element during 426 incremental validation, such as when positional arguments are used 427 in a constructor or material is appended either explicitly or 428 through parsing a DOM instance.""" 429 430 instance = None 431 """The binding for which the L{value} could not be associated with an element.""" 432 433 automaton_configuration = None 434 """The L{pyxb.binding.content.AutomatonConfiguration} representing the current state of the L{instance} content.""" 435 436 value = None 437 """The value that could not be associated with allowable content.""" 438
439 - def __init__ (self, instance, automaton_configuration, value, location=None):
440 """@param instance: the value for the L{instance} attribute. 441 @param automaton_configuration: the value for the L{automaton_configuration} attribute. 442 @param value: the value for the L{value} attribute. 443 @param location: the value for the L{location} attribute.""" 444 self.instance = instance 445 self.automaton_configuration = automaton_configuration 446 self.value = value 447 self.location = location 448 super(IncrementalElementContentError, self).__init__(instance, automaton_configuration, value, location)
449
450 -class UnrecognizedContentError (IncrementalElementContentError):
451 """Element or element-like content could not be validly associated with an sub-element in the content model. 452 453 This exception occurs when content is added to an element during incremental validation.""" 454
455 - def __str__ (self):
456 value = self.value 457 try: 458 value = str(self.value._element().name()) 459 except: 460 pass 461 acceptable = self.automaton_configuration.acceptableContent() 462 if 0 == acceptable: 463 expect = 'no more content' 464 else: 465 import pyxb.binding.content 466 seen = set() 467 names = [] 468 for u in acceptable: 469 if isinstance(u, pyxb.binding.content.ElementUse): 470 n = str(u.elementBinding().name()) 471 else: 472 assert isinstance(u, pyxb.binding.content.WildcardUse) 473 n = 'xs:any' 474 if not (n in seen): 475 names.append(n) 476 seen.add(n) 477 expect = ' or '.join(names) 478 location = '' 479 if self.location is not None: 480 location = ' at %s' % (self.location,) 481 return 'Invalid content %s%s (expect %s)' % (value, location, expect)
482
483 - def details (self):
484 import pyxb.binding.basis 485 import pyxb.binding.content 486 i = self.instance 487 rv = [ ] 488 if i._element() is not None: 489 rv.append('The containing element %s is defined at %s.' % (i._element().name(), i._element().xsdLocation())) 490 rv.append('The containing element type %s is defined at %s' % (self.instance._Name(), str(self.instance._XSDLocation))) 491 if self.location is not None: 492 rv.append('The unrecognized content %s begins at %s' % (self.value._diagnosticName(), self.location)) 493 else: 494 rv.append('The unrecognized content is %s' % (self.value._diagnosticName(),)) 495 ty = type(self.instance) 496 rv.append('The %s automaton %s in an accepting state.' % (self.instance._Name(), self.automaton_configuration.isAccepting() and "is" or "is not")) 497 if isinstance(self.instance, pyxb.binding.basis.complexTypeDefinition) and self.instance._IsMixed(): 498 rv.append('Character information content would be permitted.') 499 acceptable = self.automaton_configuration.acceptableContent() 500 if 0 == len(acceptable): 501 rv.append('No elements or wildcards would be accepted at this point.') 502 else: 503 rv.append('The following element and wildcard content would be accepted:') 504 rv2 = [] 505 for u in acceptable: 506 if isinstance(u, pyxb.binding.content.ElementUse): 507 rv2.append('An element %s per %s' % (u.elementBinding().name(), u.xsdLocation())) 508 else: 509 assert isinstance(u, pyxb.binding.content.WildcardUse) 510 rv2.append('A wildcard per %s' % (u.xsdLocation(),)) 511 rv.append('\t' + '\n\t'.join(rv2)) 512 return '\n'.join(rv)
513
514 -class BatchElementContentError (ContentValidationError):
515 """Element/wildcard content cannot be reconciled with the required content model. 516 517 This exception occurs in post-construction validation using a 518 fresh validating automaton.""" 519 520 instance = None 521 """The binding instance being constructed.""" 522 523 automaton_configuration = None 524 """The L{pyxb.binding.content.AutomatonConfiguration} representing the current state of the L{instance} content.""" 525 526 symbols = None 527 """The sequence of symbols that were accepted as content prior to the error.""" 528 529 symbol_set = None 530 """The leftovers from L{pyxb.binding.basis.complexTypeDefinition._symbolSet} that could not be reconciled with the content model.""" 531
532 - def __init__ (self, instance, automaton_configuration, symbols, symbol_set):
533 """@param instance: the value for the L{instance} attribute. 534 @param automaton_configuration: the value for the L{automaton_configuration} attribute. 535 @param symbols: the value for the L{symbols} attribute. 536 @param symbol_set: the value for the L{symbol_set} attribute.""" 537 self.instance = instance 538 self.automaton_configuration = automaton_configuration 539 self.symbols = symbols 540 self.symbol_set = symbol_set 541 super(BatchElementContentError, self).__init__(instance, automaton_configuration, symbols, symbol_set)
542
543 - def details (self):
544 import pyxb.binding.basis 545 import pyxb.binding.content 546 i = self.instance 547 rv = [ ] 548 if i._element() is not None: 549 rv.append('The containing element %s is defined at %s.' % (i._element().name(), i._element().xsdLocation())) 550 rv.append('The containing element type %s is defined at %s' % (self.instance._Name(), str(self.instance._XSDLocation))) 551 ty = type(self.instance) 552 rv.append('The %s automaton %s in an accepting state.' % (self.instance._Name(), self.automaton_configuration.isAccepting() and "is" or "is not")) 553 if 0 == len(self.symbols): 554 rv.append('No content has been accepted') 555 else: 556 rv.append('The last accepted content was %s' % (self.symbols[-1][1]._diagnosticName(),)) 557 if isinstance(self.instance, pyxb.binding.basis.complexTypeDefinition) and self.instance._IsMixed(): 558 rv.append('Character information content would be permitted.') 559 acceptable = self.automaton_configuration.acceptableSymbols() 560 if 0 == len(acceptable): 561 rv.append('No elements or wildcards would be accepted at this point.') 562 else: 563 rv.append('The following element and wildcard content would be accepted:') 564 rv2 = [] 565 for u in acceptable: 566 if isinstance(u, pyxb.binding.content.ElementUse): 567 rv2.append('An element %s per %s' % (u.elementBinding().name(), u.xsdLocation())) 568 else: 569 assert isinstance(u, pyxb.binding.content.WildcardUse) 570 rv2.append('A wildcard per %s' % (u.xsdLocation(),)) 571 rv.append('\t' + '\n\t'.join(rv2)) 572 if 0 == len(self.symbol_set): 573 rv.append('No content remains unconsumed') 574 else: 575 rv.append('The following content was not processed by the automaton:') 576 rv2 = [] 577 for (ed, syms) in self.symbol_set.iteritems(): 578 if ed is None: 579 rv2.append('xs:any (%u instances)' % (len(syms),)) 580 else: 581 rv2.append('%s (%u instances)' % (ed.name(), len(syms))) 582 rv.append('\t' + '\n\t'.join(rv2)) 583 return '\n'.join(rv)
584
585 -class IncompleteElementContentError (BatchElementContentError):
586 """Validation of an instance failed to produce an accepting state. 587 588 This exception occurs in batch-mode validation.""" 589 pass
590
591 -class UnprocessedElementContentError (BatchElementContentError):
592 """Validation of an instance produced an accepting state but left element material unconsumed. 593 594 This exception occurs in batch-mode validation.""" 595 pass
596
597 -class SimpleTypeValueError (ValidationError):
598 """Raised when a simple type value does not satisfy its constraints.""" 599 type = None 600 """The L{pyxb.binding.basis.simpleTypeDefinition} that constrains values.""" 601 602 value = None 603 """The value that violates the constraints of L{type}. In some 604 cases this is a tuple of arguments passed to a constructor that 605 failed with a built-in exception likeC{ValueError} or 606 C{OverflowError}.""" 607
608 - def __init__ (self, type, value, location=None):
609 """@param type: the value for the L{type} attribute. 610 @param value: the value for the L{value} attribute. 611 @param location: the value for the L{location} attribute. Default taken from C{value} if possible.""" 612 import pyxb.utils.utility 613 self.type = type 614 self.value = value 615 if (location is None) and isinstance(value, pyxb.utils.utility.Locatable_mixin): 616 location = value._location() 617 self.location = location 618 super(SimpleTypeValueError, self).__init__(type, value, location)
619
620 -class SimpleListValueError (SimpleTypeValueError):
621 """Raised when a list simple type contains a member that does not satisfy its constraints. 622 623 In this case, L{type} is the type of the list, and value 624 C{type._ItemType} is the type for which the L{value} is 625 unacceptable.""" 626
627 - def __str__ (self):
628 return 'Member type %s of list type %s cannot accept %s' % (self.type._ItemType._Name(), self.type._Name(), self.value)
629
630 -class SimpleUnionValueError (SimpleTypeValueError):
631 """Raised when a union simple type contains a member that does not satisfy its constraints. 632 633 In this case, L{type} is the type of the union, and the value 634 C{type._MemberTypes} is the set of types for which the value is 635 unacceptable. 636 637 The L{value} itself is the tuple of arguments passed to the 638 constructor for the union.""" 639
640 - def __str__ (self):
641 return 'No memberType of %s can be constructed from %s' % (self.type._Name(), self.value)
642
643 -class SimpleFacetValueError (SimpleTypeValueError):
644 """Raised when a simple type value does not satisfy a facet constraint. 645 646 This extends L{SimpleTypeValueError} with the L{facet} field which 647 can be used to determine why the value is unacceptable.""" 648 649 type = None 650 """The L{pyxb.binding.basis.simpleTypeDefinition} that constrains values.""" 651 652 value = None 653 """The value that violates the constraints of L{type}. In some 654 cases this is a tuple of arguments passed to a constructor that 655 failed with a built-in exception likeC{ValueError} or 656 C{OverflowError}.""" 657 658 facet = None 659 """The specific facet that is violated by the value.""" 660
661 - def __init__ (self, type, value, facet, location=None):
662 """@param type: the value for the L{type} attribute. 663 @param value: the value for the L{value} attribute. 664 @param facet: the value for the L{facet} attribute. 665 @param location: the value for the L{location} attribute. Default taken from C{value} if possible.""" 666 import pyxb.utils.utility 667 668 self.type = type 669 self.value = value 670 self.facet = facet 671 if (location is None) and isinstance(value, pyxb.utils.utility.Locatable_mixin): 672 location = value._location() 673 self.location = location 674 # Bypass immediate parent 675 super(SimpleTypeValueError, self).__init__(type, value, facet)
676
677 - def __str__ (self):
678 return 'Type %s %s constraint violated by value %s' % (self.type._Name(), self.facet._Name, self.value)
679
680 -class SimplePluralValueError (SimpleTypeValueError):
681 """Raised when context requires a plural value. 682 683 Unlike L{SimpleListValueError}, in this case the plurality is 684 external to C{type}, for example when an element has simple 685 content and allows multiple occurrences.""" 686 pass
687
688 -class AttributeValidationError (ValidationError):
689 """Raised when an attribute requirement is not satisfied.""" 690 691 type = None 692 """The L{pyxb.binding.basis.complexTypeDefinition} subclass of the instance.""" 693 694 tag = None 695 """The name of the attribute.""" 696 697 instance = None 698 """The binding instance, if available.""" 699
700 - def __init__ (self, type, tag, instance=None, location=None):
701 """@param type: the value for the L{type} attribute. 702 @param tag: the value for the L{tag} attribute. 703 @param instance: the value for the L{instance} attribute. 704 @param location: the value for the L{location} attribute. Default taken from C{instance} if possible. 705 """ 706 import pyxb.utils.utility as utility 707 self.type = type 708 self.tag = tag 709 self.instance = instance 710 if (location is None) and isinstance(instance, utility.Locatable_mixin): 711 location = instance._location() 712 self.location = location 713 super(AttributeValidationError, self).__init__(type, tag, instance, location)
714
715 -class UnrecognizedAttributeError (AttributeValidationError):
716 """Attempt to reference an attribute not sanctioned by content model.""" 717 pass
718
719 -class ProhibitedAttributeError (AttributeValidationError):
720 """Raised when an attribute that is prohibited is set or referenced in an element."""
721 - def __str__ (self):
722 return 'Attempt to reference prohibited attribute %s in type %s' % (self.tag, self.type)
723
724 -class MissingAttributeError (AttributeValidationError):
725 """Raised when an attribute that is required is missing in an element."""
726 - def __str__ (self):
727 return 'Instance of %s lacks required attribute %s' % (self.type, self.tag)
728
729 -class AttributeChangeError (AttributeValidationError):
730 """Attempt to change an attribute that has a fixed value constraint."""
731 - def __str__ (self):
732 return 'Cannot change fixed attribute %s in type %s' % (self.tag, self.type)
733
734 -class BindingError (PyXBException):
735 """Raised when the bindings are mis-used. 736 737 These are not validation errors, but rather structural errors. 738 For example, attempts to extract complex content from a type that 739 requires simple content, or vice versa. """
740
741 -class NotSimpleContentError (BindingError):
742 """An operation that requires simple content was invoked on a 743 complex type instance that does not have simple content.""" 744 745 instance = None 746 """The binding instance which should have had simple content.""" 747
748 - def __init__ (self, instance):
749 """@param instance: the binding instance that was mis-used. 750 This will be available in the L{instance} attribute.""" 751 self.instance = instance 752 super(BindingError, self).__init__(instance)
753 pass 754
755 - def __str__ (self):
756 return 'type %s does not have simple content' % (self.instance._Name(),)
757
758 -class NotComplexContentError (BindingError):
759 """An operation that requires a content model was invoked on a 760 complex type instance that has empty or simple content.""" 761 762 instance = None 763 """The binding instance which should have had a content model.""" 764
765 - def __init__ (self, instance):
766 """@param instance: the binding instance that was mis-used. 767 This will be available in the L{instance} attribute.""" 768 self.instance = instance 769 super(BindingError, self).__init__(instance)
770
771 - def __str__ (self):
772 return 'type %s has simple/empty content' % (self.instance._Name(),)
773
774 -class ReservedNameError (BindingError):
775 """Reserved name set in binding instance.""" 776 777 instance = None 778 """The binding instance.""" 779 780 name = None 781 """The name that was caught being assigned""" 782
783 - def __init__ (self, instance, name):
784 """@param instance: the value for the L{instance} attribute. 785 p@param name: the value for the L{name} attribute.""" 786 self.instance = instance 787 self.name = name 788 super(ReservedNameError, self).__init__(instance, name)
789
790 - def __str__ (self):
791 return '%s is a reserved name within %s' % (self.name, self.instance._Name())
792
793 -class PyXBError (exceptions.Exception):
794 """Base class for exceptions that indicate a problem that the user probably can't fix.""" 795 pass
796
797 -class UsageError (PyXBError):
798 """Raised when the code detects user violation of an API."""
799
800 -class LogicError (PyXBError):
801 """Raised when the code detects an implementation problem."""
802
803 -class IncompleteImplementationError (LogicError):
804 """Raised when required capability has not been implemented. 805 806 This is only used where it is reasonable to expect the capability 807 to be present, such as a feature of XML schema that is not 808 supported (e.g., the redefine directive)."""
809