Package pyxb :: Package xmlschema :: Module structures
[hide private]
[frames] | no frames]

Source Code for Module pyxb.xmlschema.structures

   1  # Copyright 2009, Peter A. Bigot 
   2  # 
   3  # Licensed under the Apache License, Version 2.0 (the "License"); you may 
   4  # not use this file except in compliance with the License. You may obtain a 
   5  # copy of the License at: 
   6  # 
   7  #            http://www.apache.org/licenses/LICENSE-2.0 
   8  # 
   9  # Unless required by applicable law or agreed to in writing, software 
  10  # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
  11  # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
  12  # License for the specific language governing permissions and limitations 
  13  # under the License. 
  14   
  15  """Classes corresponding to W3C XML Schema components. 
  16   
  17  Class names and behavior should conform to the schema components described in 
  18  U{XML Schema Part 1: Structures<http://www.w3.org/TR/xmlschema-1/>}. 
  19  References to sections in the documentation of this module generally refers to 
  20  that document. 
  21   
  22  Each class has a C{CreateFromDOM} class method that creates an instance and 
  23  initializes it from a DOM node.  Only the L{Wildcard}, L{Particle}, and 
  24  L{ModelGroup} components are created from non-DOM sources.  However, the 
  25  requirements on DOM interface are restricted to attributes, child nodes, and 
  26  basic fields, though all these must support namespaces. 
  27   
  28  @group Mixins: *_mixin 
  29  @group Ur Type Specializations: *UrType* 
  30  @group Utilities: _PluralityData, _ImportElementInformationItem 
  31   
  32  """ 
  33   
  34  import traceback 
  35  import pyxb 
  36  import pyxb.xmlschema 
  37  from xml.dom import Node 
  38  import xml.dom 
  39  import types 
  40  import re 
  41   
  42  import pyxb.namespace.archive 
  43  import pyxb.namespace.resolution 
  44   
  45  from pyxb.binding import basis 
  46  from pyxb.binding import datatypes 
  47  from pyxb.binding import facets 
  48  from pyxb.utils.domutils import * 
  49  import pyxb.utils.utility 
  50  import copy 
  51  import urllib2 
  52  import urlparse 
  53  import os.path 
  54   
  55  # Flag indicating that the built in types have been registered 
  56  _PastAddBuiltInTypes = False 
  57   
  58  # Make it easier to check node names in the XMLSchema namespace 
  59  from pyxb.namespace import XMLSchema as xsd 
60 61 -class _SchemaComponent_mixin (pyxb.namespace._ComponentDependency_mixin, 62 pyxb.namespace.archive._ArchivableObject_mixin, 63 pyxb.utils.utility.PrivateTransient_mixin, 64 pyxb.utils.utility.Locatable_mixin):
65 """A mix-in that marks the class as representing a schema component. 66 67 This exists so that we can determine the owning schema for any 68 component we encounter. This is normally done at construction 69 time by passing a C{schema=val} parameter to the constructor. 70 """ 71 72 # This class suppports transient instance variables. These variables are 73 # added to the set of transients at the point of declaration in the class. 74 __PrivateTransient = set() 75
76 - def _namespaceContext (self):
77 """The namespace context for this schema. 78 79 This defines where it looks things up, where it puts things it 80 createas, the in-scope namespace declarations, etc. Must be defined 81 for anything that does any sort of QName interpretation. The value is 82 generally a reference to a namespace context associated with the DOM 83 element node corresponding to this component.""" 84 if self.__namespaceContext is None: 85 raise pyxb.LogicError('Attempt to access missing namespace context for %s' % (self,)) 86 return self.__namespaceContext
87 - def _clearNamespaceContext (self):
88 self.__namespaceContext = None 89 return self
90 __namespaceContext = None 91 __PrivateTransient.add('namespaceContext') 92 93 # The name by which this component is known within the binding module. 94 # This is in component rather than _NamedComponent_mixin because some 95 # unnamed components (like ModelGroup and Wildcard) have Python objects to 96 # represent them, so need a binding-level name. 97 __nameInBinding = None 98 99 # The schema component that owns this. If C{None}, the component is owned 100 # directly by the schema. 101 __owner = None 102 __PrivateTransient.add('owner') 103 104 # The schema components owned by this component. 105 __ownedComponents = None 106 __PrivateTransient.add('ownedComponent') 107
108 - def _scope (self):
109 """The context into which declarations in or subordinate to this nodeare placed.""" 110 return self.__scope
111 __scope = None 112
113 - def _scopeIsIndeterminate (self):
114 """Return True iff nobody has defined a scope for this node.""" 115 return _ScopedDeclaration_mixin.ScopeIsIndeterminate(self._scope())
116
117 - def _scopeIsGlobal (self):
118 """Return True iff this component has global scope.""" 119 return _ScopedDeclaration_mixin.ScopeIsGlobal(self._scope())
120
121 - def _setScope (self, ctd):
122 """Set the scope of this instance after construction. 123 124 This should only be invoked on cloned declarations being incorporated 125 into a complex type definition. Note that the source of the clone may 126 be any scope: indeterminate if from a model (attribute) group 127 definition; global if a reference to a global component; or ctd if 128 inherited from a complex base type.""" 129 assert self.__cloneSource is not None 130 assert isinstance(self, _ScopedDeclaration_mixin) 131 assert isinstance(ctd, ComplexTypeDefinition) 132 self.__scope = ctd 133 return self
134
135 - def __init__ (self, *args, **kw):
136 """Initialize portions of a component. 137 138 @keyword scope: The scope in which the component is defined 139 140 @keyword namespace_context: The NamespaceContext to use within this component 141 142 @keyword node: If no C{namespace_context} is provided, a DOM node must 143 be provided from which a namespace context can be identified. 144 145 @keyword owner: Reference to the component that owns this one (the 146 immediately enclosing component). Is C{None} in the case of top-level 147 components. 148 149 @keyword schema: Reference to the L{Schema} component to which the 150 component belongs. Required for every component except L{Schema}, 151 L{Annotation}, and L{Wildcard}. 152 """ 153 154 self.__ownedComponents = set() 155 self.__scope = kw.get('scope') 156 self.__namespaceContext = kw.get('namespace_context') 157 node = kw.get('node') 158 if self.__namespaceContext is None: 159 if node is None: 160 raise pyxb.LogicError('Schema component constructor must be given namespace_context or node') 161 self.__namespaceContext = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node) 162 if self.__namespaceContext is None: 163 raise pyxb.LogicError('No namespace_context for schema component') 164 if isinstance(node, pyxb.utils.utility.Locatable_mixin): 165 self._setLocation(node.location) 166 167 super(_SchemaComponent_mixin, self).__init__(*args, **kw) 168 self._namespaceContext().targetNamespace()._associateComponent(self) 169 170 self._setOwner(kw.get('owner')) 171 172 schema = kw.get('schema') 173 if schema is not None: 174 self._setObjectOrigin(schema.originRecord()) 175 else: 176 assert isinstance(self, (Schema, Annotation, Wildcard)), 'No origin available for type %s' % (type(self),) 177 178 if isinstance(self, ComplexTypeDefinition): 179 assert 1 < len(self.__namespaceContext.inScopeNamespaces())
180 181
182 - def _dissociateFromNamespace (self):
183 """Dissociate this component from its owning namespace. 184 185 This should only be done whwen there are no other references to the 186 component, and you want to ensure it does not appear in the model.""" 187 self._namespaceContext().targetNamespace()._replaceComponent(self, None) 188 return self
189
190 - def _setOwner (self, owner):
191 """Set the owner of this component. 192 193 If C{owner} is C{None}, this has no effect. Otherwise, the 194 component's current owner must be either C{None} or the same as the 195 input C{owner}.""" 196 197 if owner is not None: 198 assert (self.__owner is None) or (self.__owner == owner), 'Owner was %s set to %s' % (self.__owner, owner) 199 self.__owner = owner 200 owner.__ownedComponents.add(self) 201 return self
202
203 - def owner (self):
204 return self.__owner
205 206 # A reference to the instance from which this instance was cloned. 207 __cloneSource = None 208 __PrivateTransient.add('cloneSource') 209
210 - def _cloneSource (self):
211 """The source component from which this is a clone. 212 213 Returns C{None} if this is not a clone.""" 214 return self.__cloneSource
215 216 # A set of references to all instances that are clones of this one. 217 __clones = None 218 __PrivateTransient.add('clones') 219
220 - def _clones (self):
221 """The set of instances cloned from this component. 222 223 Returns None if no instances have been cloned from this.""" 224 return self.__clones
225
226 - def _resetClone_csc (self, **kw):
227 """Virtual method to clear whatever attributes should be reset in a 228 cloned component. 229 230 This instance should be an instance created by copy.copy(). 231 232 The implementation in this class clears the owner and dependency 233 relations. 234 235 Returns C{self}. 236 """ 237 assert self.__cloneSource is not None 238 owner = kw['owner'] 239 self.__nameInBinding = None 240 self.__owner = owner 241 assert not (isinstance(self, ComplexTypeDefinition) and isinstance(owner, Schema)) 242 self.__ownedComponents = set() 243 self.__clones = None 244 owner._namespaceContext().targetNamespace()._associateComponent(self) 245 if self.__namespaceContext is None: 246 # When cloning imported components, loan them the owner's 247 # namespace context, only so that their cloned children can be 248 # associated with the same namespace. 249 self.__namespaceContext = owner._namespaceContext() 250 return getattr(super(_SchemaComponent_mixin, self), '_resetClone_csc', lambda *_args,**_kw: self)(**kw)
251
252 - def _clone (self, owner, origin):
253 """Create a copy of this instance suitable for adoption by some other 254 component. 255 256 This is used for creating a locally-scoped declaration from a 257 declaration in a named model or attribute group.""" 258 259 # We only care about cloning declarations, and they should 260 # have an unassigned scope. However, we do clone 261 # non-declarations that contain cloned declarations. 262 #assert (not isinstance(self, _ScopedDeclaration_mixin)) or self._scopeIsIndeterminate() 263 if isinstance(self, pyxb.namespace.resolution._Resolvable_mixin): 264 assert self.isResolved() 265 266 assert owner is not None 267 that = copy.copy(self) 268 that.__cloneSource = self 269 if self.__clones is None: 270 self.__clones = set() 271 self.__clones.add(that) 272 that._resetClone_csc(owner=owner, origin=origin) 273 if isinstance(that, pyxb.namespace.resolution._Resolvable_mixin): 274 assert that.isResolved() 275 return that
276
277 - def isTypeDefinition (self):
278 """Return True iff this component is a simple or complex type 279 definition.""" 280 return isinstance(self, (SimpleTypeDefinition, ComplexTypeDefinition))
281
282 - def isUrTypeDefinition (self):
283 """Return True iff this component is a simple or complex type 284 definition.""" 285 return isinstance(self, (_SimpleUrTypeDefinition, _UrTypeDefinition))
286
287 - def bestNCName (self):
288 """Return the name of this component, as best it can be determined. 289 290 For example, ModelGroup instances will be named by their 291 ModelGroupDefinition, if available. Returns None if no name can be 292 inferred.""" 293 if isinstance(self, _NamedComponent_mixin): 294 return self.name() 295 if isinstance(self, ModelGroup): 296 agd = self.modelGroupDefinition() 297 if agd is not None: 298 return agd.name() 299 return None
300
301 - def nameInBinding (self):
302 """Return the name by which this component is known in the generated 303 binding. 304 305 @note: To support builtin datatypes, type definitions with an 306 associated L{pythonSupport<SimpleTypeDefinition.pythonSupport>} class 307 initialize their binding name from the class name when the support 308 association is created. As long as no built-in datatype conflicts 309 with a language keyword, this should be fine.""" 310 return self.__nameInBinding
311
312 - def hasBinding (self):
313 """Return C{True} iff this is a component which has a user-visible 314 Python construct which serves as its binding. 315 316 Type definitions have classes as their bindings. Global element 317 declarations have instances of L{pyxb.binding.basis.element} as their 318 bindings.""" 319 return self.isTypeDefinition() or (isinstance(self, ElementDeclaration) and self._scopeIsGlobal())
320
321 - def setNameInBinding (self, name_in_binding):
322 """Set the name by which this component shall be known in the XSD binding.""" 323 self.__nameInBinding = name_in_binding 324 return self
325
326 - def _updateFromOther_csc (self, other):
327 """Override fields in this instance with those from the other. 328 329 Post-extended; description in leaf implementation in 330 ComplexTypeDefinition and SimpleTypeDefinition.""" 331 assert self != other 332 getattr(super(_SchemaComponent_mixin, self), '_updateFromOther_csc', lambda *args, **kw: self)(other) 333 # The only thing we update is the binding name, and that only if it's new. 334 if self.__nameInBinding is None: 335 self.__nameInBinding = other.__nameInBinding 336 return self
337
338 -class _Singleton_mixin (pyxb.cscRoot):
339 """This class is a mix-in which guarantees that only one instance 340 of the class will be created. It is used to ensure that the 341 ur-type instances are pointer-equivalent even when unpickling. 342 See ComplexTypeDefinition.UrTypeDefinition()."""
343 - def __new__ (cls, *args, **kw):
344 singleton_property = '_%s__singleton' % (cls.__name__,) 345 if not (singleton_property in cls.__dict__): 346 setattr(cls, singleton_property, super(_Singleton_mixin, cls).__new__(cls, *args, **kw)) 347 return cls.__dict__[singleton_property]
348
349 -class _Annotated_mixin (pyxb.cscRoot):
350 """Mix-in that supports an optional single annotation that describes the component. 351 352 Most schema components have annotations. The ones that don't are 353 L{AttributeUse}, L{Particle}, and L{Annotation}. L{ComplexTypeDefinition} 354 and L{Schema} support multiple annotations, so do not mix-in this 355 class.""" 356 357 # Optional Annotation instance 358 __annotation = None 359
360 - def __init__ (self, *args, **kw):
361 super(_Annotated_mixin, self).__init__(*args, **kw) 362 self.__annotation = kw.get('annotation')
363
364 - def _annotationFromDOM (self, node):
365 cn = LocateUniqueChild(node, 'annotation') 366 if cn is not None: 367 kw = { } 368 if isinstance(self, _SchemaComponent_mixin): 369 kw['owner'] = self 370 self.__annotation = Annotation.CreateFromDOM(cn, **kw)
371
372 - def _updateFromOther_csc (self, other):
373 """Override fields in this instance with those from the other. 374 375 Post-extended; description in leaf implementation in 376 ComplexTypeDefinition and SimpleTypeDefinition.""" 377 assert self != other 378 getattr(super(_Annotated_mixin, self), '_updateFromOther_csc', lambda *args, **kw: self)(other) 379 # @todo: make this a copy? 380 self.__annotation = other.__annotation 381 return self
382
383 - def annotation (self):
384 return self.__annotation
385
386 -class _PickledAnonymousReference (pyxb.cscRoot):
387 """A helper that encapsulates a reference to an anonymous type in a different namespace. 388 389 Normally references to components in other namespaces can be made using 390 the component's name. This is not the case when a namespace derives from 391 a base type in another namespace and needs to reference the attribute or 392 element declarations held in that type. If these declarations are local 393 to the base complex type, they cannot be identified by name. This class 394 provides a pickleable representation for them that behaves rather like an 395 L{pyxb.namespace.ExpandedName} instance in that it can be used to 396 dereference various component types.""" 397 398 __AnonymousCategory = pyxb.namespace.archive.NamespaceArchive._AnonymousCategory() 399 400 __namespace = None 401 __anonymousName = None
402 - def __init__ (self, namespace, anonymous_name):
403 """Create a new anonymous reference. 404 405 @param namespace: The namespace in which the component is declared. 406 @type namespace: L{pyxb.namespace.Namespace} 407 @param anonymous_name: A generated name guaranteed to be unique within 408 the namespace. See L{_NamedComponent_mixin._anonymousName}. 409 @type anonymous_name: C{basestring}. 410 """ 411 self.__namespace = namespace 412 self.__anonymousName = anonymous_name 413 assert self.__anonymousName is not None
414 415 @classmethod
416 - def FromPickled (cls, object_reference):
417 """Return the component referred to by the provided reference, 418 regardless of whether it is a normal or anonymous reference.""" 419 if not isinstance(object_reference, _PickledAnonymousReference): 420 assert isinstance(object_reference, tuple) 421 object_reference = pyxb.namespace.ExpandedName(object_reference) 422 return object_reference
423
424 - def namespace (self):
425 return self.__namespace
426
427 - def anonymousName (self):
428 return self.__anonymousName
429
430 - def validateComponentModel (self):
431 """Forward to the associated namespace.""" 432 return self.__namespace.validateComponentModel()
433
434 - def __lookupObject (self):
435 #print 'Lookup %s' % (self,) 436 return self.__namespace.categoryMap(self.__AnonymousCategory).get(self.__anonymousName)
437 438 typeDefinition = __lookupObject 439 """Return the attribute group definition referenced by this instance, or 440 C{None} if the reference is not to an attribute group definition.""" 441 442 attributeGroupDefinition = __lookupObject 443 modelGroupDefinition = __lookupObject 444 attributeDeclaration = __lookupObject 445 elementDeclaration = __lookupObject 446 identityConstraintDefinition = __lookupObject 447 notationDeclaration = __lookupObject 448
449 - def __str__ (self):
450 """Represent the anonymous reference in a form recognizable by a developer.""" 451 return 'ANONYMOUS:%s' % (pyxb.namespace.ExpandedName(self.__namespace, self.__anonymousName),)
452
453 -class _NamedComponent_mixin (pyxb.utils.utility.PrivateTransient_mixin, pyxb.cscRoot):
454 """Mix-in to hold the name and targetNamespace of a component. 455 456 The name may be None, indicating an anonymous component. The 457 targetNamespace is never None, though it could be an empty namespace. The 458 name and targetNamespace values are immutable after creation. 459 460 This class overrides the pickling behavior: when pickling a Namespace, 461 objects that do not belong to that namespace are pickled as references, 462 not as values. This ensures the uniqueness of objects when multiple 463 namespace definitions are pre-loaded. 464 465 This class must follow L{_SchemaComponent_mixin} in the MRO. 466 """ 467 468 __PrivateTransient = set() 469
470 - def name (self):
471 """Name of the component within its scope or namespace. 472 473 This is an NCName. The value isNone if the component is 474 anonymous. The attribute is immutable after the component is 475 created creation.""" 476 return self.__name
477 __name = None 478
479 - def isAnonymous (self):
480 """Return true iff this instance is locally scoped (has no name).""" 481 return self.__name is None
482
483 - def _setAnonymousName (self, namespace, unique_id=None, anon_name=None):
484 # If this already has a name, keep using it. 485 if self.__anonymousName is not None: 486 return 487 assert self.__needAnonymousSupport() 488 assert namespace is not None 489 if self.bindingNamespace() is not None: 490 assert self.bindingNamespace() == namespace 491 if self.targetNamespace() is not None: 492 assert self.targetNamespace() == namespace 493 if anon_name is None: 494 anon_name = self.nameInBinding() 495 if anon_name is None: 496 anon_name = self.name() 497 if anon_name is None: 498 anon_name = 'ANON_IN_GROUP' 499 if unique_id is not None: 500 anon_name = '%s_%s' % (anon_name, unique_id) 501 anon_name = pyxb.utils.utility.MakeUnique(anon_name, set(namespace.categoryMap(self.__AnonymousCategory).keys())) 502 self.__anonymousName = anon_name 503 namespace.addCategoryObject(self.__AnonymousCategory, anon_name, self)
504 - def _anonymousName (self, namespace=None):
505 assert self.__anonymousName is not None, '%x %s %s in %s missing anonymous name' % (id(self), type(self), self.name(), self.targetNamespace()) 506 return self.__anonymousName
507 __anonymousName = None 508
509 - def targetNamespace (self):
510 """The targetNamespace of a component. 511 512 This is None, or a reference to a Namespace in which the 513 component is declared (either as a global or local to one of 514 the namespace's complex type definitions). This is immutable 515 after creation. 516 """ 517 return self.__targetNamespace
518 __targetNamespace = None 519
520 - def bindingNamespace (self):
521 """The namespace in which this component's binding is placed.""" 522 return self.__bindingNamespace
523 - def _setBindingNamespace (self, namespace):
525 __bindingNamespace = None 526
527 - def _templateMap (self):
528 """A map from template keys to component-specific values. 529 530 This is used in code generation to maintain unique names for accessor 531 methods, identifiers, keys, and other characteristics associated with 532 the code generated in support of the binding for this component.""" 533 return self.__templateMap
534 __templateMap = None 535 536 __AnonymousCategory = pyxb.namespace.archive.NamespaceArchive._AnonymousCategory() 537
538 - def __needAnonymousSupport (self):
539 # If this component doesn't have a name, or if it's in some scope in 540 # which it cannot be located in a category map, we'll need a unique 541 # name for it. 542 return self.isAnonymous() or (self._scopeIsIndeterminate() and not isinstance(self, (AttributeGroupDefinition, ModelGroupDefinition)))
543
544 - def _schema (self):
545 """Return the schema component from which this component was defined. 546 547 Needed so we can distinguish components that came from different 548 locations, since that imposes an external order dependency on them and 549 on cross-namespace inclusions. 550 551 @note: This characteristic is removed when the component is stored in 552 a namespace archive.""" 553 return self.__schema
554 __schema = None 555 __PrivateTransient.add('schema') 556
557 - def _prepareForArchive_csc (self, module_record):
558 if self.__needAnonymousSupport(): 559 self._setAnonymousName(module_record.namespace(), unique_id=module_record.generationUID()) 560 return getattr(super(_NamedComponent_mixin, self), '_prepareForArchive_csc', lambda *_args,**_kw: self)(module_record)
561
562 - def _picklesInArchive (self, archive):
563 """Return C{True} if this component should be pickled by value in the 564 given namespace. 565 566 When pickling, a declaration component is considered to belong to the 567 namespace if it has a local scope which belongs to the namespace. In 568 that case, the declaration is a clone of something that does not 569 belong to the namespace; but the clone does. 570 571 @see: L{_bindsInNamespace} 572 573 @return: C{False} if the component should be pickled by reference. 574 """ 575 if isinstance(self._scope(), ComplexTypeDefinition): 576 return self._scope()._picklesInArchive(archive) 577 assert not (self.targetNamespace() is None), '%s has no tns, scope %s, location %s, schema %s' % (self, self._scope(), self._location(), self._schema().targetNamespace()) 578 assert not (self._objectOrigin() is None) 579 old_flag = (self.targetNamespace() in archive.namespaces()) 580 new_flag = (self._objectOrigin().generationUID() == archive.generationUID()) 581 #assert old_flag == new_flag, '%s %s %s %s' % (old_flag, new_flag, self, self._picklingReference()) 582 return new_flag # old_flag # and new_flag
583
584 - def _bindsInNamespace (self, ns):
585 """Return C{True} if the binding for this component should be 586 generated in the given namespace. 587 588 This is the case when the component is in the given namespace. It's 589 also the case when the component has no associated namespace (but not 590 an absent namespace). Be aware that cross-namespace inheritance means 591 you will get references to elements in another namespace when 592 generating code for a subclass; that's fine, and those references 593 should not be generated locally. 594 """ 595 return self.targetNamespace() in (ns, None)
596
597 - def expandedName (self):
598 """Return the L{pyxb.namespace.ExpandedName} of this object.""" 599 if self.name() is None: 600 return None 601 return pyxb.namespace.ExpandedName(self.targetNamespace(), self.name())
602
603 - def __new__ (cls, *args, **kw):
604 """Pickling support. 605 606 Normally, we just create a new instance of this class. 607 However, if we're unpickling a reference in a loadable schema, 608 we need to return the existing component instance by looking 609 up the name in the component map of the desired namespace. We 610 can tell the difference because no normal constructors that 611 inherit from this have positional arguments; only invocations 612 by unpickling with a value returned in __getnewargs__ do. 613 614 This does require that the dependent namespace already have 615 been validated (or that it be validated here). That shouldn't 616 be a problem, except for the dependency loop resulting from 617 use of xml:lang in the XMLSchema namespace. For that issue, 618 see pyxb.namespace._XMLSchema. 619 """ 620 621 if 0 == len(args): 622 rv = super(_NamedComponent_mixin, cls).__new__(cls) 623 return rv 624 ( object_reference, scope, icls ) = args 625 626 object_reference = _PickledAnonymousReference.FromPickled(object_reference) 627 628 # Explicitly validate here: the lookup operations won't do so, 629 # but will abort if the namespace hasn't been validated yet. 630 object_reference.validateComponentModel() 631 if isinstance(scope, (tuple, _PickledAnonymousReference)): 632 # Scope is the expanded name of the complex type in which the 633 # named value can be located. 634 scope_ref = _PickledAnonymousReference.FromPickled(scope) 635 if object_reference.namespace() != scope_ref.namespace(): 636 scope_ref.validateComponentModel() 637 assert 'typeDefinition' in scope_ref.namespace().categories() 638 scope_ctd = scope_ref.typeDefinition() 639 if scope_ctd is None: 640 raise pyxb.SchemaValidationError('Unable to resolve local scope %s' % (scope_ref,)) 641 if issubclass(icls, AttributeDeclaration): 642 rv = scope_ctd.lookupScopedAttributeDeclaration(object_reference) 643 elif issubclass(icls, ElementDeclaration): 644 rv = scope_ctd.lookupScopedElementDeclaration(object_reference) 645 else: 646 raise pyxb.IncompleteImplementationError('Scope %s reference lookup of %s not implemented for type %s' % (scope_ref, object_reference, icls)) 647 if rv is None: 648 raise pyxb.SchemaValidationError('Unable to resolve %s as %s in scope %s' % (object_reference, icls, scope_ref)) 649 elif _ScopedDeclaration_mixin.ScopeIsGlobal(scope) or _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope): 650 if (issubclass(icls, SimpleTypeDefinition) or issubclass(icls, ComplexTypeDefinition)): 651 rv = object_reference.typeDefinition() 652 elif issubclass(icls, AttributeGroupDefinition): 653 rv = object_reference.attributeGroupDefinition() 654 elif issubclass(icls, ModelGroupDefinition): 655 rv = object_reference.modelGroupDefinition() 656 elif issubclass(icls, AttributeDeclaration): 657 rv = object_reference.attributeDeclaration() 658 elif issubclass(icls, ElementDeclaration): 659 rv = object_reference.elementDeclaration() 660 elif issubclass(icls, IdentityConstraintDefinition): 661 rv = object_reference.identityConstraintDefinition() 662 else: 663 raise pyxb.IncompleteImplementationError('Reference lookup of %s not implemented for type %s' % (object_reference, icls)) 664 if rv is None: 665 raise pyxb.SchemaValidationError('Unable to resolve %s as %s' % (object_reference, icls)) 666 else: 667 raise pyxb.IncompleteImplementationError('Unable to resolve reference %s, scope %s ns %s type %s, class %s' % (object_reference, scope, scope.targetNamespace(), type(scope), icls)) 668 return rv
669
670 - def __init__ (self, *args, **kw):
671 assert 0 == len(args) 672 name = kw.get('name') 673 # Must be None or a valid NCName 674 assert (name is None) or (0 > name.find(':')), 'name %s' % (name,) 675 self.__name = name 676 677 # Target namespace is taken from the context, unless somebody 678 # overrides it (as is done for local declarations if the form is 679 # unqualified). 680 self.__targetNamespace = kw.get('target_namespace', self._namespaceContext().targetNamespace()) 681 self.__bindingNamespace = kw.get('binding_namespace') 682 683 self.__templateMap = {} 684 685 self.__schema = kw.get('schema') 686 assert self._schema() is not None 687 688 # Do parent invocations after we've set the name: they might need it. 689 super(_NamedComponent_mixin, self).__init__(*args, **kw)
690
691 - def isNameEquivalent (self, other):
692 """Return true iff this and the other component share the same name and target namespace. 693 694 Anonymous components are inherently name inequivalent, except to 695 themselves. This relies on equivalence as defined for 696 pyxb.namespace.ExpandedName, for which None is not equivalent to any 697 non-anonymous name.""" 698 # Note that unpickled objects 699 return (self == other) or ((not self.isAnonymous()) and (self.expandedName() == other.expandedName()))
700
701 - def isTypeEquivalent (self, other):
702 """Return True iff this and the other component have matching types. 703 704 It appears that name equivalence is used; two complex type definitions 705 with identical structures are not considered equivalent (at least, per 706 XMLSpy). 707 """ 708 return (type(self) == type(other)) and self.isNameEquivalent(other)
709
710 - def isDerivationConsistent (self, other):
711 """Return True iff this type can serve as a restriction of the other 712 type for the purposes of U{element consistency<http://www.w3.org/TR/xmlschema-1/#cos-element-consistent>}. 713 714 It appears that name equivalence is normally used; two complex type 715 definitions with identical structures are not considered equivalent 716 (at least, per XMLSpy). However, some OpenGIS standards demonstrate 717 that derivation by restriction from the other type is also acceptable. 718 That opens a whole can of worms; see 719 L{ElementDeclaration.isAdaptable}. 720 """ 721 this = self 722 # can this succeed if component types are not equivalent? 723 while this is not None: 724 if this.isTypeEquivalent(other): 725 return True 726 print 'Checking %s against %s' % (this, other) 727 if not (this.isResolved() and other.isResolved()): 728 raise pyxb.IncompleteImplementationError('Oh fudge. Somebody violated the assumptions in ElementDeclaration.isAdaptable.') 729 if isinstance(self, ComplexTypeDefinition): 730 if self.DM_restriction != this.derivationMethod(): 731 return False 732 elif isinstance(self, SimpleTypeDefinition): 733 if self._DA_restriction != this._derivationAlternative(): 734 return False 735 else: 736 raise pyxb.IncompleteImplementationError('Need derivation consistency check for type %s' % (type(this),)) 737 this = this.baseTypeDefinition() 738 if this.isUrTypeDefinition(): 739 # Well, this certainly can't be a valid restriction of 740 # anything else. 741 break 742 return False
743
744 - def _picklingReference (self):
745 if self.__needAnonymousSupport(): 746 #print 'Wrapping %s as anonymous %s in %s' % (self, self._anonymousName(), self.targetNamespace()) 747 assert self._anonymousName() is not None 748 return _PickledAnonymousReference(self.targetNamespace(), self._anonymousName()) 749 return self.expandedName().uriTuple()
750
751 - def __pickleAsReference (self):
752 if self.targetNamespace() is None: 753 return False 754 # Get the namespace we're pickling. If the namespace is None, 755 # we're not pickling; we're probably cloning, and in that case 756 # we don't want to use the reference state encoding. 757 pickling_archive = pyxb.namespace.archive.NamespaceArchive.PicklingArchive() 758 if pickling_archive is None: 759 return False 760 # If this thing is scoped in a complex type that belongs to the 761 # namespace being pickled, then it gets pickled as an object even if 762 # its target namespace isn't this one. 763 assert self._objectOrigin() is not None 764 if self._picklesInArchive(pickling_archive): 765 return False 766 # Note that anonymous objects must use their fallback 767 return True
768
769 - def __getstate__ (self):
770 if self.__pickleAsReference(): 771 # NB: This instance may be a scoped declaration, but in 772 # this case (unlike getnewargs) we don't care about trying 773 # to look up a previous instance, so we don't need to 774 # encode the scope in the reference tuple. 775 return self._picklingReference() 776 if self.targetNamespace() is None: 777 # The only internal named objects that should exist are 778 # ones that have a non-global scope (including those with 779 # absent scope). 780 # @todo: this is wrong for schema that are not bound to a 781 # namespace, unless we use an unbound Namespace instance 782 #print type(self) 783 #assert isinstance(self, _ScopedDeclaration_mixin) 784 #assert self.SCOPE_global != self.scope() 785 # NOTE: The name of the scope may be None. This is not a 786 # problem unless somebody tries to extend or restrict the 787 # scope type, which at the moment I'm thinking is 788 # impossible for anonymous types. If it isn't, we're 789 # gonna need some other sort of ID, like a UUID associated 790 # with the anonymous class at the time it's written to the 791 # preprocessed schema file. 792 pass 793 return super(_NamedComponent_mixin, self).__getstate__()
794
795 - def __getnewargs__ (self):
796 """Pickling support. 797 798 If this instance is being pickled as a reference, provide the 799 arguments that are necessary so that the unpickler can locate 800 the appropriate component rather than create a duplicate 801 instance.""" 802 803 if self.__pickleAsReference(): 804 scope = self._scope() 805 if isinstance(self, _ScopedDeclaration_mixin): 806 # If scope is global, we can look it up in the namespace. 807 # If scope is indeterminate, this must be within a group in 808 # another namespace. Why are we serializing it? 809 # If scope is local, provide the namespace and name of 810 # the type that holds it 811 if self.SCOPE_global == self.scope(): 812 pass 813 elif isinstance(self.scope(), ComplexTypeDefinition): 814 scope = self.scope()._picklingReference() 815 assert isinstance(scope, (tuple, _PickledAnonymousReference)), self 816 elif self._scopeIsIndeterminate(): 817 # This is actually OK: we made sure both the scope and 818 # this instance can be looked up by a unique identifier. 819 pass 820 else: 821 raise pyxb.IncompleteImplementationError('pickling unrecognized scope %s type %s' % (self.scope(), type(self.scope()))) 822 else: 823 assert isinstance(self, _NamedComponent_mixin), 'Pickling unnamed component %s in indeterminate scope by reference' % (self,) 824 assert not isinstance(scope, ComplexTypeDefinition), '%s %s %s %s' % (self, self.name(), scope, self._objectOrigin()) 825 826 rv = ( self._picklingReference(), scope, self.__class__ ) 827 return rv 828 return ()
829
830 - def __setstate__ (self, state):
831 if isinstance(state, tuple): 832 # We don't actually have to set any state here; we just 833 # make sure that we resolved to an already-configured 834 # instance. 835 assert self.targetNamespace() is not None 836 assert self.targetNamespace().uri() == state[0] 837 assert self.name() == state[1] 838 return 839 if isinstance(state, _PickledAnonymousReference): 840 assert self.targetNamespace() is not None 841 assert self.targetNamespace() == state.namespace() 842 assert self.__needAnonymousSupport() 843 assert self._anonymousName() == state.anonymousName() 844 return 845 self.__dict__.update(state)
846
847 - def _resetClone_csc (self, **kw):
848 self.__schema = None 849 rv = getattr(super(_NamedComponent_mixin, self), '_resetClone_csc', lambda *_args,**_kw: self)(**kw) 850 self.__templateMap = { } 851 origin = kw.get('origin') 852 self.__anonymousName = None 853 self._setObjectOrigin(origin, override=True) 854 return rv
855
856 -class _ValueConstraint_mixin (pyxb.cscRoot):
857 """Mix-in indicating that the component contains a simple-type 858 value that may be constrained.""" 859 860 VC_na = 0 #<<< No value constraint applies 861 VC_default = 1 #<<< Provided value constraint is default value 862 VC_fixed = 2 #<<< Provided value constraint is fixed value 863 864 # None, or a tuple containing a string followed by one of the VC_* 865 # values above. 866 __valueConstraint = None
867 - def valueConstraint (self):
868 """A constraint on the value of the attribute or element. 869 870 Either None, or a pair consisting of a string in the lexical 871 space of the typeDefinition and one of VC_default and 872 VC_fixed.""" 873 return self.__valueConstraint
874
875 - def default (self):
876 """If this instance constraints a default value, return that 877 value; otherwise return None.""" 878 if not isinstance(self.__valueConstraint, tuple): 879 return None 880 if self.VC_default != self.__valueConstraint[1]: 881 return None 882 return self.__valueConstraint[0]
883
884 - def fixed (self):
885 """If this instance constraints a fixed value, return that 886 value; otherwise return None.""" 887 if not isinstance(self.__valueConstraint, tuple): 888 return None 889 if self.VC_fixed != self.__valueConstraint[1]: 890 return None 891 return self.__valueConstraint[0]
892
893 - def _valueConstraintFromDOM (self, node):
894 aval = NodeAttribute(node, 'default') 895 if aval is not None: 896 self.__valueConstraint = (aval, self.VC_default) 897 return self 898 aval = NodeAttribute(node, 'fixed') 899 if aval is not None: 900 self.__valueConstraint = (aval, self.VC_fixed) 901 return self 902 self.__valueConstraint = None 903 return self
904
905 -class _ScopedDeclaration_mixin (pyxb.cscRoot):
906 """Mix-in class for named components that have a scope. 907 908 Scope is important when doing cross-namespace inheritance, 909 e.g. extending or restricting a complex type definition that is 910 from a different namespace. In this case, we will need to retain 911 a reference to the external component when the schema is 912 serialized. 913 914 This is done in the pickling process by including the scope when 915 pickling a component as a reference. The scope is the 916 SCOPE_global if global; otherwise, it is a tuple containing the 917 external namespace URI and the NCName of the complex type 918 definition in that namespace. We assume that the complex type 919 definition has global scope; otherwise, it should not have been 920 possible to extend or restrict it. (Should this be untrue, there 921 are comments in the code about a possible solution.) 922 923 @warning: This mix-in must follow L{_NamedComponent_mixin} in the C{mro}. 924 """ 925 926 SCOPE_global = 'global' #<<< Marker to indicate global scope 927 XSCOPE_indeterminate = 'indeterminate' #<<< Marker to indicate scope has not been assigned 928 929 @classmethod
930 - def IsValidScope (cls, value):
931 return (cls.SCOPE_global == value) or isinstance(value, ComplexTypeDefinition)
932 933 @classmethod
934 - def ScopeIsIndeterminate (cls, value):
935 return (cls.XSCOPE_indeterminate == value)
936 937 @classmethod
938 - def ScopeIsGlobal (cls, value):
939 return (cls.SCOPE_global == value)
940
941 - def _scopeIsCompatible (self, scope):
942 """Return True if this scope currently assigned to this instance is compatible with the given scope. 943 944 If either scope is indeterminate, presume they will ultimately be 945 compatible. Scopes that are equal are compatible, as is a local scope 946 if this already has a global scope.""" 947 if self.ScopeIsIndeterminate(scope) or self.ScopeIsIndeterminate(self.scope()): 948 return True 949 if self.scope() == scope: 950 return True 951 return (self.SCOPE_global == self.scope()) and isinstance(scope, ComplexTypeDefinition)
952 953 # The scope for the element. Valid values are SCOPE_global or a 954 # complex type definition. None is an invalid value, but may 955 # appear if scope is determined by an ancestor component.
956 - def scope (self):
957 """The scope for the declaration. 958 959 Valid values are SCOPE_global, or a complex type definition. 960 A value of None means a non-global declaration that is not 961 owned by a complex type definition. These can only appear in 962 attribute group definitions or model group definitions. 963 964 @todo: For declarations in named model groups (viz., local 965 elements that aren't references), the scope needs to be set by 966 the owning complex type. 967 """ 968 return self._scope()
969 970 # The base declaration is the original _ScopedDeclaration_mixin which 971 # introduced the element into its scope. This is used to retain a 972 # particular defining declaration when each extension type gets its own 973 # clone adapted for its scope. 974 __baseDeclaration = None
975 - def baseDeclaration (self):
976 return self.__baseDeclaration or self
977 - def _baseDeclaration (self, referenced_declaration):
978 self.__baseDeclaration = referenced_declaration.baseDeclaration() 979 return self.__baseDeclaration
980
981 -class _PluralityData (types.ListType):
982 """This class represents an abstraction of the set of documents conformant 983 to a particle or particle term. 984 985 The abstraction of a given document is a map from element declarations 986 that can appear at the top level of the document to a boolean that is true 987 iff there could be multiple instances of that element declaration at the 988 top level of a valid document. The abstraction of the set is a list of 989 document abstractions. 990 991 This information is used in binding generation to determine whether a 992 field associated with a tag might need to hold multiple instances. 993 """ 994 995 @classmethod
996 - def _MapUnion (self, map1, map2):
997 """Given two maps, return an updated map indicating the unified 998 plurality.""" 999 umap = { } 1000 for k in set(map1.keys()).union(map2.keys()): 1001 if k in map1: 1002 umap[k] = (k in map2) or map1[k] 1003 else: 1004 umap[k] = map2[k] 1005 return umap
1006
1007 - def combinedPlurality (self):
1008 """Combine all the document abstractions into a single one that covers 1009 all possible documents. 1010 1011 The combined plurality is simply the elemental maximum over all 1012 document abstractions. 1013 """ 1014 1015 combined_plurality = { } 1016 for pdm in self: 1017 for (ed, v) in pdm.items(): 1018 if isinstance(ed, ElementDeclaration): 1019 assert ed.baseDeclaration() == ed 1020 combined_plurality[ed] = combined_plurality.get(ed, False) or v 1021 elif isinstance(ed, Wildcard): 1022 pass 1023 else: 1024 raise pyxb.LogicError('Unexpected plurality index %s' % (ed,)) 1025 return combined_plurality
1026
1027 - def __fromModelGroup (self, model_group):
1028 # Start by collecting the data for each of the particles. 1029 pdll = [ _PluralityData(_p) for _p in model_group.particles() ] 1030 #dumpmap = lambda _pdm: ', '.join( [ '%s: %s' % (_ed.expandedName(), _pl) for (_ed, _pl) in _pdm.items() ]) 1031 #dumpmapset = lambda _pd: '(' + ') | ('.join([ dumpmap(_pdm) for _pdm in _pd ]) + ')' 1032 if (ModelGroup.C_CHOICE == model_group.compositor()): 1033 # Plurality for choice is simply any of the pluralities of the particles 1034 [ self.extend(_pd) for _pd in pdll ] 1035 elif ((ModelGroup.C_SEQUENCE == model_group.compositor()) or (ModelGroup.C_ALL == model_group.compositor())): 1036 # Sequence means all of them, in all their glory. All is treated 1037 # the same way. Essentially this is a pointwise OR of the 1038 # pluralities of the particles. 1039 if 0 < len(pdll): 1040 new_pd = pdll.pop() 1041 for pd in pdll: 1042 assert 0 < len(pd) 1043 assert 0 < len(new_pd) 1044 stage_pd = [ ] 1045 for pdm1 in new_pd: 1046 for pdm2 in pd: 1047 stage_pd.append(self._MapUnion(pdm1, pdm2)) 1048 new_pd = stage_pd 1049 self.extend(new_pd) 1050 else: 1051 raise pyxb.LogicError('Unrecognized compositor value %s' % (model_group.compositor(),))
1052
1053 - def __fromParticle (self, particle):
1054 assert particle.isResolved() 1055 pd = particle.term().pluralityData() 1056 1057 # If the particle can't appear at all, there are no results. 1058 if 0 == particle.maxOccurs(): 1059 return 1060 1061 # If the particle can only occur once, it has no effect on the 1062 # pluralities; use the term to identify them 1063 if 1 == particle.maxOccurs(): 1064 self.__setFromComponent(particle.term()) 1065 return 1066 1067 # If there are multiple alternatives, assume they are all 1068 # taken. Do this by creating a map that treats every possible 1069 # element as appearing multiple times. 1070 true_map = {} 1071 pd = _PluralityData(particle.term()) 1072 while 0 < len(pd): 1073 pdm = pd.pop() 1074 [ true_map.setdefault(_k, True) for _k in pdm.keys() ] 1075 self.append(true_map)
1076
1077 - def __setFromComponent (self, component=None):
1078 del self[:] 1079 if isinstance(component, ElementDeclaration): 1080 assert component.isResolved() 1081 assert isinstance(component.baseDeclaration(), ElementDeclaration) 1082 self.append( { component.baseDeclaration(): False } ) 1083 #self.append( { component: False } ) 1084 elif isinstance(component, ModelGroup): 1085 self.__fromModelGroup(component) 1086 elif isinstance(component, Particle): 1087 self.__fromParticle(component) 1088 elif isinstance(component, Wildcard): 1089 pass 1090 elif component is not None: 1091 raise pyxb.NotImplementedError("No support for plurality of component type %s" % (type(component),)) 1092 # Elements get lost if there's a result set that doesn't have any 1093 # documents in it. 1094 if 0 == len(self): 1095 self.append({})
1096
1097 - def __init__ (self, component=None):
1098 super(_PluralityData, self).__init__() 1099 self.__setFromComponent(component)
1100
1101 -class _AttributeWildcard_mixin (pyxb.cscRoot):
1102 """Support for components that accept attribute wildcards. 1103 1104 That is L{AttributeGroupDefinition} and L{ComplexTypeDefinition}. The 1105 calculations of the appropriate wildcard are sufficiently complex that 1106 they need to be abstracted out to a mix-in class.""" 1107 1108 # Optional wildcard that constrains attributes 1109 __attributeWildcard = None 1110
1111 - def attributeWildcard (self):
1112 """Return the L{Wildcard} component associated with attributes of this 1113 instance, or C{None} if attribute wildcards are not present in the 1114 instance.""" 1115 return self.__attributeWildcard
1116
1117 - def _setAttributeWildcard (self, attribute_wildcard):
1118 """Set the attribute wildcard property for this instance.""" 1119 assert (attribute_wildcard is None) or isinstance(attribute_wildcard, Wildcard) 1120 self.__attributeWildcard = attribute_wildcard 1121 return self
1122
1123 - def _attributeRelevantChildren (self, node_list):
1124 """Return the nodes that are relevant for attribute processing. 1125 1126 @param node_list: A sequence of nodes found in a definition content 1127 information item. 1128 1129 @return: A tuple C{( attributes, attributeGroups, attributeWildcard)} 1130 where C{attributes} is the subsequence of C{node_list} that are 1131 XMLSchema C{attribute} nodes; C{attributeGroups} is analogous; and 1132 C{attributeWildcard} is a single DOM node with XMLSchema name 1133 C{anyAttribute} (or C{None}, if no such node is present in the list). 1134 1135 @raise pyxb.SchemaValidationError: An C{attributeGroup} node is 1136 present but does not have the required C{ref} attribute. 1137 @raise pyxb.SchemaValidationError: Multiple C{anyAttribute} nodes are 1138 identified. 1139 """ 1140 1141 attributes = [] 1142 attribute_groups = [] 1143 any_attribute = None 1144 # Handle clauses 1 and 2 (common between simple and complex types) 1145 for node in node_list: 1146 if Node.ELEMENT_NODE != node.nodeType: 1147 continue 1148 if xsd.nodeIsNamed(node, 'attribute'): 1149 # Note: This attribute use instance may have use=prohibited 1150 attributes.append(node) 1151 elif xsd.nodeIsNamed(node, 'attributeGroup'): 1152 # This must be an attributeGroupRef 1153 agd_attr = NodeAttribute(node, 'ref') 1154 if agd_attr is None: 1155 raise pyxb.SchemaValidationError('Require ref attribute on internal attributeGroup elements') 1156 attribute_groups.append(agd_attr) 1157 elif xsd.nodeIsNamed(node, 'anyAttribute'): 1158 if any_attribute is not None: 1159 raise pyxb.SchemaValidationError('Multiple anyAttribute children are not allowed') 1160 any_attribute = node 1161 1162 return (attributes, attribute_groups, any_attribute)
1163 1164 @classmethod
1165 - def CompleteWildcard (cls, namespace_context, attribute_groups, local_wildcard):
1166 """Implement the algorithm as described the 1167 U{specification<http://www.w3.org/TR/xmlschema-1/#declare-type>}. 1168 1169 @param namespace_context: The L{pyxb.namespace.NamespaceContext} to be 1170 associated with any created L{Wildcard} instance 1171 @param attribute_groups: A list of L{AttributeGroupDefinition} instances 1172 @param local_wildcard: A L{Wildcard} instance computed from a relevant 1173 XMLSchema C{anyAttribute} element, or C{None} if no attribute wildcard 1174 is relevant 1175 """ 1176 1177 # Non-absent wildcard properties of attribute groups 1178 agd_wildcards = [] 1179 for agd in attribute_groups: 1180 assert isinstance(agd, AttributeGroupDefinition) 1181 if agd.attributeWildcard() is not None: 1182 agd_wildcards.append(agd.attributeWildcard()) 1183 agd_constraints = [ _agd.namespaceConstraint() for _agd in agd_wildcards ] 1184 1185 # Clause 2.1 1186 if 0 == len(agd_wildcards): 1187 return local_wildcard 1188 1189 if local_wildcard is not None: 1190 # Clause 2.2.1 1191 return Wildcard(process_contents=local_wildcard.processContents(), 1192 namespace_constraint=Wildcard.IntensionalIntersection(agd_constraints + [local_wildcard.namespaecConstraint()]), 1193 annotation=local_wildcard.annotation(), 1194 namespace_context=namespace_context) 1195 # Clause 2.2.2 1196 return Wildcard(process_contents=agd_wildcards[0].processContents(), 1197 namespace_constraint=Wildcard.IntensionalIntersection(agd_constraints), 1198 namespace_context=namespace_context)
1199
1200 -class AttributeDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _ValueConstraint_mixin, _ScopedDeclaration_mixin):
1201 """An XMLSchema U{Attribute Declaration<http://www.w3.org/TR/xmlschema-1/#cAttribute_Declarations>} component. 1202 """ 1203 1204 # The STD to which attribute values must conform 1205 __typeDefinition = None
1206 - def typeDefinition (self):
1207 """The simple type definition to which an attribute value must 1208 conform.""" 1209 return self.__typeDefinition
1210
1211 - def __init__ (self, *args, **kw):
1212 super(AttributeDeclaration, self).__init__(*args, **kw) 1213 assert 'scope' in kw
1214
1215 - def __str__ (self):
1216 if self.typeDefinition(): 1217 return 'AD[%s:%s]' % (self.name(), self.typeDefinition().expandedName()) 1218 return 'AD[%s:?]' % (self.expandedName(),)
1219 1220 @classmethod
1221 - def CreateBaseInstance (cls, name, schema, std=None):
1222 """Create an attribute declaration component for a specified namespace.""" 1223 kw = { 'name' : name, 1224 'schema' : schema, 1225 'namespace_context' : schema.targetNamespace().initialNamespaceContext(), 1226 'scope' : _ScopedDeclaration_mixin.SCOPE_global } 1227 assert schema is not None 1228 bi = cls(**kw) 1229 if std is not None: 1230 bi.__typeDefinition = std 1231 bi.__typeAttribute = None 1232 return bi
1233 1234 # CFD:AD CFD:AttributeDeclaration 1235 @classmethod
1236 - def CreateFromDOM (cls, node, **kw):
1237 """Create an attribute declaration from the given DOM node. 1238 1239 wxs is a Schema instance within which the attribute is being 1240 declared. 1241 1242 node is a DOM element. The name must be one of ( 'all', 1243 'choice', 'sequence' ), and the node must be in the XMLSchema 1244 namespace. 1245 1246 scope is the _ScopeDeclaration_mxin context into which the 1247 attribute declaration is placed. It can be SCOPE_global, a 1248 complex type definition, or XSCOPE_indeterminate if this is an 1249 anonymous declaration within an attribute group. It is a 1250 required parameter for this function. 1251 """ 1252 1253 scope = kw['scope'] 1254 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope) 1255 1256 # Node should be an XMLSchema attribute node 1257 assert xsd.nodeIsNamed(node, 'attribute') 1258 1259 name = NodeAttribute(node, 'name') 1260 1261 # Implement per section 3.2.2 1262 if xsd.nodeIsNamed(node.parentNode, 'schema'): 1263 assert cls.SCOPE_global == scope 1264 elif NodeAttribute(node, 'ref') is None: 1265 # This is an anonymous declaration within an attribute use 1266 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition) 1267 else: 1268 raise pyxb.SchemaValidationError('Internal attribute declaration by reference') 1269 1270 rv = cls(name=name, node=node, **kw) 1271 rv._annotationFromDOM(node) 1272 rv._valueConstraintFromDOM(node) 1273 1274 rv.__typeAttribute = NodeAttribute(node, 'type') 1275 1276 kw.pop('node', None) 1277 kw['owner'] = rv 1278 1279 st_node = LocateUniqueChild(node, 'simpleType') 1280 if st_node is not None: 1281 rv.__typeDefinition = SimpleTypeDefinition.CreateFromDOM(st_node, **kw) 1282 elif rv.__typeAttribute is None: 1283 rv.__typeDefinition = SimpleTypeDefinition.SimpleUrTypeDefinition() 1284 1285 if rv.__typeDefinition is None: 1286 rv._queueForResolution('creation') 1287 return rv
1288
1289 - def isResolved (self):
1290 return self.__typeDefinition is not None
1291 1292 # res:AD res:AttributeDeclaration
1293 - def _resolve (self):
1294 if self.isResolved(): 1295 return self 1296 1297 # Although the type definition may not be resolved, *this* component 1298 # is resolved, since we don't look into the type definition for anything. 1299 assert self.__typeAttribute is not None, 'AD %s is unresolved but has no typeAttribute field' % (self.expandedName(),) 1300 type_en = self._namespaceContext().interpretQName(self.__typeAttribute) 1301 self.__typeDefinition = type_en.typeDefinition() 1302 if self.__typeDefinition is None: 1303 raise pyxb.SchemaValidationError('Type reference %s cannot be found' % (type_en,)) 1304 if not isinstance(self.__typeDefinition, SimpleTypeDefinition): 1305 raise pyxb.SchemaValidationError('Need %s to be a simple type' % (type_ln,)) 1306 1307 return self
1308
1309 - def _updateFromOther_csc (self, other):
1310 """Override fields in this instance with those from the other. 1311 1312 This method is invoked only by Schema._addNamedComponent, and 1313 then only when a built-in type collides with a schema-defined 1314 type. Material like facets is not (currently) held in the 1315 built-in copy, so the DOM information is copied over to the 1316 built-in STD, which is subsequently re-resolved. 1317 1318 Returns self. 1319 """ 1320 assert self != other 1321 assert self.name() is not None 1322 assert self.isNameEquivalent(other) 1323 super(AttributeDeclaration, self)._updateFromOther_csc(other) 1324 1325 # The other STD should be an unresolved schema-defined type. 1326 # Mark this instance as unresolved so it is re-examined 1327 if not other.isResolved(): 1328 if pyxb.namespace.BuiltInObjectUID == self._objectOrigin().generationUID(): 1329 #assert self.isResolved(), 'Built-in %s is not resolved' % (self.expandedName(),) 1330 print '**!!**!! Not destroying builtin %s: %s' % (self.expandedName(), self.__typeDefinition) 1331 else: 1332 self.__typeDefinition = None 1333 return self
1334 1335 # bR:AD
1336 - def _bindingRequires_vx (self, include_lax):
1337 """Attribute declarations require their type.""" 1338 return frozenset([ self.__typeDefinition ])
1339
1340 -class AttributeUse (_SchemaComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _ValueConstraint_mixin):
1341 """An XMLSchema U{Attribute Use<http://www.w3.org/TR/xmlschema-1/#cAttribute_Use>} component.""" 1342 1343 # How this attribute can be used. The component property 1344 # "required" is true iff the value is USE_required. 1345 __use = None 1346 1347 USE_required = 0x01 #<<< The attribute is required 1348 USE_optional = 0x02 #<<< The attribute may or may not appear 1349 USE_prohibited = 0x04 #<<< The attribute must not appear
1350 - def required (self): return self.USE_required == self.__use
1351 - def prohibited (self): return self.USE_prohibited == self.__use
1352 1353 __restrictionOf = None
1354 - def restrictionOf (self):
1355 return self.__restrictionOf
1356 - def _setRestrictionOf (self, au):
1357 assert isinstance(au, AttributeUse) 1358 # Might re-assign if had to suspend resolution 1359 assert (self.__restrictionOf is None) or (self.__restrictionOf == au) 1360 self.__restrictionOf = au
1361 1362 # A reference to an AttributeDeclaration
1363 - def attributeDeclaration (self):
1364 """The attribute declaration for this use. 1365 1366 When the use scope is assigned, the declaration is cloned (if 1367 necessary) so that each declaration corresponds to only one use. We 1368 rely on this in code generation, because the template map for the use 1369 is stored in its declaration.""" 1370 return self.__attributeDeclaration
1371 __attributeDeclaration = None 1372 1373 # Define so superclasses can take keywords
1374 - def __init__ (self, **kw):
1375 super(AttributeUse, self).__init__(**kw)
1376
1377 - def matchingQNameMembers (self, au_set):
1378 """Return the subset of au_set for which the use names match this use.""" 1379 1380 if not self.isResolved(): 1381 return None 1382 this_ad = self.attributeDeclaration() 1383 rv = set() 1384 for au in au_set: 1385 if not au.isResolved(): 1386 return None 1387 that_ad = au.attributeDeclaration() 1388 if this_ad.isNameEquivalent(that_ad): 1389 rv.add(au) 1390 return rv
1391 1392 @classmethod
1393 - def CreateBaseInstance (cls, schema, attribute_declaration, use=USE_optional):
1394 kw = { 'schema' : schema, 1395 'namespace_context' : schema.targetNamespace().initialNamespaceContext() } 1396 bi = cls(**kw) 1397 assert isinstance(attribute_declaration, AttributeDeclaration) 1398 bi.__attributeDeclaration = attribute_declaration 1399 bi.__use = use 1400 return bi
1401 1402 # CFD:AU CFD:AttributeUse 1403 @classmethod
1404 - def CreateFromDOM (cls, node, **kw):
1405 """Create an Attribute Use from the given DOM node. 1406 1407 wxs is a Schema instance within which the attribute use is 1408 being defined. 1409 1410 node is a DOM element. The name must be 'attribute', and the 1411 node must be in the XMLSchema namespace. 1412 1413 scope is the _ScopeDeclaration_mixin context into which any 1414 required anonymous attribute declaration is put. This must be 1415 a complex type definition, or None if this use is in an 1416 attribute group. 1417 """ 1418 1419 scope = kw['scope'] 1420 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition) 1421 assert xsd.nodeIsNamed(node, 'attribute') 1422 schema = kw['schema'] 1423 rv = cls(node=node, **kw) 1424 1425 rv.__use = cls.USE_optional 1426 use = NodeAttribute(node, 'use') 1427 if use is not None: 1428 if 'required' == use: 1429 rv.__use = cls.USE_required 1430 elif 'optional' == use: 1431 rv.__use = cls.USE_optional 1432 elif 'prohibited' == use: 1433 rv.__use = cls.USE_prohibited 1434 else: 1435 raise pyxb.SchemaValidationError('Unexpected value %s for attribute use attribute' % (use,)) 1436 1437 rv._valueConstraintFromDOM(node) 1438 1439 rv.__refAttribute = NodeAttribute(node, 'ref') 1440 if rv.__refAttribute is None: 1441 # Create an anonymous declaration 1442 kw.pop('node', None) 1443 kw['owner'] = rv 1444 kw['target_namespace'] = schema.targetNamespaceForNode(node, AttributeDeclaration) 1445 rv.__attributeDeclaration = AttributeDeclaration.CreateFromDOM(node, **kw) 1446 1447 if not rv.isResolved(): 1448 rv._queueForResolution('creation') 1449 1450 return rv
1451
1452 - def isResolved (self):
1453 return self.__attributeDeclaration is not None
1454
1455 - def _resolve (self):
1456 if self.isResolved(): 1457 return self 1458 ad_en = self._namespaceContext().interpretQName(self.__refAttribute) 1459 self.__attributeDeclaration = ad_en.attributeDeclaration() 1460 if self.__attributeDeclaration is None: 1461 raise pyxb.SchemaValidationError('Attribute declaration %s cannot be found' % (ad_en,)) 1462 1463 assert isinstance(self.__attributeDeclaration, AttributeDeclaration) 1464 1465 return self
1466 1467 # bR:AU
1468 - def _bindingRequires_vx (self, include_lax):
1469 """Attribute uses require their declarations, but only if lax.""" 1470 if not include_lax: 1471 return frozenset() 1472 return frozenset([ self.attributeDeclaration() ])
1473 1474 # aFS:AU
1475 - def _adaptForScope (self, ctd):
1476 """Adapt this instance for the given complex type. 1477 1478 If the attribute declaration for this use is not associated with a 1479 complex type definition, then associate a clone of it with this CTD, 1480 and clone a new attribute use that uses the associated declaration. 1481 This attribute use is then inherited by extensions and restrictions, 1482 while retaining its original scope.""" 1483 rv = self 1484 assert self.isResolved() 1485 ad = self.__attributeDeclaration 1486 assert ad.scope() is not None 1487 assert isinstance(ctd, ComplexTypeDefinition) 1488 if not isinstance(ad.scope(), ComplexTypeDefinition): 1489 rv = self._clone(ctd, ctd._objectOrigin()) 1490 rv.__attributeDeclaration = ad._clone(rv, ctd._objectOrigin()) 1491 rv.__attributeDeclaration._setScope(ctd) 1492 ctd._recordLocalDeclaration(rv.__attributeDeclaration) 1493 return rv
1494
1495 - def __str__ (self):
1496 return 'AU[%s]' % (self.attributeDeclaration(),)
1497
1498 1499 -class ElementDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _ValueConstraint_mixin, _ScopedDeclaration_mixin):
1500 """An XMLSchema U{Element Declaration<http://www.w3.org/TR/xmlschema-1/#cElement_Declarations>} component.""" 1501 1502 # Simple or complex type definition 1503 __typeDefinition = None
1504 - def typeDefinition (self):
1505 """The simple or complex type to which the element value conforms.""" 1506 return self.__typeDefinition
1507 - def _typeDefinition (self, type_definition):
1508 self.__typeDefinition = type_definition 1509 return self
1510 1511 __nillable = False
1512 - def nillable (self): return self.__nillable
1513 1514 __identityConstraintDefinitions = None
1516 """A list of IdentityConstraintDefinition instances.""" 1517 return self.__identityConstraintDefinitions
1518 1519 __substitutionGroupAffiliation = None
1521 """None, or a reference to an ElementDeclaration.""" 1522 return self.__substitutionGroupAffiliation
1523 1524 SGE_none = 0 #<<< No substitution group exclusion specified 1525 SGE_extension = 0x01 #<<< Substitution by an extension of the base type 1526 SGE_restriction = 0x02 #<<< Substitution by a restriction of the base type 1527 SGE_substitution = 0x04 #<<< Substitution by replacement (?) 1528 1529 _SGE_Map = { 'extension' : SGE_extension 1530 , 'restriction' : SGE_restriction } 1531 _DS_Map = _SGE_Map.copy() 1532 _DS_Map.update( { 'substitution' : SGE_substitution } ) 1533 1534 # Subset of SGE marks formed by bitmask. SGE_substitution is disallowed. 1535 __substitutionGroupExclusions = SGE_none 1536 1537 # Subset of SGE marks formed by bitmask 1538 __disallowedSubstitutions = SGE_none 1539 1540 __abstract = False
1541 - def abstract (self): return self.__abstract
1542
1543 - def pluralityData (self):
1544 """Return the plurality information for this component. 1545 1546 An ElementDeclaration produces one instance of a single element.""" 1547 return _PluralityData(self)
1548
1549 - def hasWildcardElement (self):
1550 """Return False, since element declarations are not wildcards.""" 1551 return False
1552 1553 # bR:ED
1554 - def _bindingRequires_vx (self, include_lax):
1555 """Element declarations depend on the type definition of their 1556 content.""" 1557 return frozenset([self.__typeDefinition])
1558
1559 - def __init__ (self, *args, **kw):
1560 super(ElementDeclaration, self).__init__(*args, **kw)
1561 1562 # CFD:ED CFD:ElementDeclaration 1563 @classmethod
1564 - def CreateFromDOM (cls, node, **kw):
1565 """Create an element declaration from the given DOM node. 1566 1567 wxs is a Schema instance within which the element is being 1568 declared. 1569 1570 scope is the _ScopeDeclaration_mixin context into which the 1571 element declaration is recorded. It can be SCOPE_global, a 1572 complex type definition, or None in the case of elements 1573 declared in a named model group. 1574 1575 node is a DOM element. The name must be 'element', and the 1576 node must be in the XMLSchema namespace.""" 1577 1578 scope = kw['scope'] 1579 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope) 1580 1581 # Node should be an XMLSchema element node 1582 assert xsd.nodeIsNamed(node, 'element') 1583 1584 # Might be top-level, might be local 1585 name = NodeAttribute(node, 'name') 1586 if xsd.nodeIsNamed(node.parentNode, 'schema'): 1587 assert _ScopedDeclaration_mixin.SCOPE_global == scope 1588 elif NodeAttribute(node, 'ref') is None: 1589 # Scope may be None or a CTD. 1590 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition) 1591 else: 1592 raise pyxb.SchemaValidationError('Created reference as element declaration') 1593 1594 rv = cls(name=name, node=node, **kw) 1595 rv._annotationFromDOM(node) 1596 rv._valueConstraintFromDOM(node) 1597 1598 rv.__substitutionGroupAttribute = NodeAttribute(node, 'substitutionGroup') 1599 1600 kw.pop('node', None) 1601 kw['owner'] = rv 1602 1603 identity_constraints = [] 1604 for cn in node.childNodes: 1605 if (Node.ELEMENT_NODE == cn.nodeType) and xsd.nodeIsNamed(cn, 'key', 'unique', 'keyref'): 1606 identity_constraints.append(IdentityConstraintDefinition.CreateFromDOM(cn, **kw)) 1607 rv.__identityConstraintDefinitions = identity_constraints 1608 1609 rv.__typeDefinition = None 1610 rv.__typeAttribute = NodeAttribute(node, 'type') 1611 simpleType_node = LocateUniqueChild(node, 'simpleType') 1612 complexType_node = LocateUniqueChild(node, 'complexType') 1613 if rv.__typeAttribute is not None: 1614 if (simpleType_node is not None) and (complexType_node is not None): 1615 raise pyxb.SchemaValidationError('Cannot combine type attribute with simpleType or complexType child') 1616 if (rv.__typeDefinition is None) and (simpleType_node is not None): 1617 rv.__typeDefinition = SimpleTypeDefinition.CreateFromDOM(simpleType_node, **kw) 1618 if (rv.__typeDefinition is None) and (complexType_node is not None): 1619 rv.__typeDefinition = ComplexTypeDefinition.CreateFromDOM(complexType_node, **kw) 1620 if rv.__typeDefinition is None: 1621 if rv.__typeAttribute is None: 1622 # Scan for particle types which were supposed to be enclosed in a complexType 1623 for cn in node.childNodes: 1624 if Particle.IsParticleNode(cn): 1625 raise pyxb.SchemaValidationError('Node %s in element must be wrapped by complexType.' % (cn.localName,)) 1626 rv.__typeDefinition = ComplexTypeDefinition.UrTypeDefinition() 1627 rv.__isResolved = (rv.__typeDefinition is not None) and (rv.__substitutionGroupAttribute is None) 1628 if not rv.__isResolved: 1629 rv._queueForResolution('creation') 1630 1631 attr_val = NodeAttribute(node, 'nillable') 1632 if attr_val is not None: 1633 rv.__nillable = datatypes.boolean(attr_val) 1634 1635 attr_val = NodeAttribute(node, 'abstract') 1636 if attr_val is not None: 1637 rv.__abstract = datatypes.boolean(attr_val) 1638 1639 schema = kw['schema'] 1640 rv.__disallowedSubstitutions = schema.blockForNode(node, cls._DS_Map) 1641 rv.__substitutionGroupExclusions = schema.finalForNode(node, cls._SGE_Map) 1642 1643 return rv
1644
1645 - def isAdaptable (self, ctd):
1646 """Determine whether this element declaration is adaptable. 1647 1648 OK, this gets ugly. First, if this declaration isn't resolved, it's 1649 clearly not adaptable. 1650 1651 Now: For it to be adaptable, we must know enough about its type to 1652 verify that it is derivation-consistent with any other uses of the 1653 same name in the same complex type. If the element's type is 1654 resolved, that's good enough. 1655 1656 If the element's type isn't resolved, we're golden as long as 1657 type-equivalent types were used. But it's also allowed for the 1658 derived ctd to use the element name constraining it to a derivation of 1659 the element base type. (Go see namespace 1660 http://www.opengis.net/ows/1.1 types PositionType, PositionType2D, 1661 BoundingBox, and WGS84BoundingBox for an example). So, we really do 1662 have to have the element's type resolved. 1663 1664 Except that if a CTD's content incorporates an element with the same 1665 type as the CTD (i.e., nested), this will never happen, because the 1666 CTD can't get resolved until after it has been resolved. 1667 (Go see {http://www.opengis.net/ows/1.1}ContentsBaseType and 1668 {http://www.opengis.net/ows/1.1}DatasetDescriptionSummaryBaseType for 1669 an example). 1670 1671 So, we give the world a break and assume that if the type we're trying 1672 to resolve is the same as the type of an element in that type, then 1673 the element type will be resolved by the point it's needed. In point 1674 of fact, it won't, but we'll only notice that if a CTD contains an 1675 element whose type is a restriction of the CTD. In that case, 1676 isDerivationConsistent will blow chunks and somebody'll have to come 1677 back and finish up this mess. 1678 """ 1679 1680 if not self.isResolved(): 1681 return False 1682 if self.typeDefinition().isResolved(): 1683 return True 1684 # Aw, dammit. See if we're gonna need the type resolved before we can 1685 # adapt this thing. 1686 existing_decl = ctd.lookupScopedElementDeclaration(self.expandedName()) 1687 if existing_decl is None: 1688 # Nobody else has this name, so we don't have to check for 1689 # consistency. 1690 return True 1691 # OK, we've got a name clash. Are the two types trivially equivalent? 1692 if self.typeDefinition().isTypeEquivalent(existing_decl.typeDefinition()): 1693 # Yes! Go for it. 1694 return True 1695 # No. Can't proceed until the type definition is resolved. Hope it 1696 # can be.... 1697 print 'WARNING: Require %s to be resolved; might be a loop.' % (self.typeDefinition(),) 1698 return False
1699 1700 # aFS:ED
1701 - def _adaptForScope (self, owner, ctd):
1702 #print 'aFS:ED %s %s old scope %s' % (self.expandedName(), ctd.expandedName(), self.scope()) 1703 rv = self 1704 assert isinstance(ctd, ComplexTypeDefinition), '%s is not a CTD' % (ctd,) 1705 if not isinstance(self.scope(), ComplexTypeDefinition): 1706 assert owner is not None 1707 rv = self._clone(owner, ctd._objectOrigin()) 1708 rv._setScope(ctd) 1709 ctd._recordLocalDeclaration(rv) 1710 return rv
1711 1712 __isResolved = False
1713 - def isResolved (self):
1714 return self.__isResolved
1715 1716 # res:ED res:ElementDeclaration
1717 - def _resolve (self):
1718 if self.isResolved(): 1719 return self 1720 1721 #if self._scopeIsIndeterminate(): 1722 # print 'WARNING: Resolving ED %s with indeterminate scope (is this a problem?)' % (self.expandedName(),) 1723 if self.__substitutionGroupAttribute is not None: 1724 sg_en = self._namespaceContext().interpretQName(self.__substitutionGroupAttribute) 1725 sga = sg_en.elementDeclaration() 1726 if sga is None: 1727 raise pyxb.SchemaValidationError('Element declaration refers to unrecognized substitution group %s' % (sg_en,)) 1728 self.__substitutionGroupAffiliation = sga 1729 1730 if self.__typeDefinition is None: 1731 assert self.__typeAttribute is not None 1732 type_en = self._namespaceContext().interpretQName(self.__typeAttribute) 1733 self.__typeDefinition = type_en.typeDefinition() 1734 if self.__typeDefinition is None: 1735 raise pyxb.SchemaValidationError('Type declaration %s cannot be found' % (type_en,)) 1736 1737 self.__isResolved = True 1738 return self
1739
1740 - def __str__ (self):
1741 if self.typeDefinition() is not None: 1742 return 'ED[%s:%s]' % (self.name(), self.typeDefinition().name()) 1743 return 'ED[%s:?]' % (self.name(),)
1744
1745 1746 -class ComplexTypeDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _AttributeWildcard_mixin):
1747 __PrivateTransient = set() 1748 1749 # The type resolved from the base attribute. 1750 __baseTypeDefinition = None
1751 - def baseTypeDefinition (self):
1752 "The type resolved from the base attribute.""" 1753 return self.__baseTypeDefinition
1754 1755 DM_empty = 0 #<<< No derivation method specified 1756 DM_extension = 0x01 #<<< Derivation by extension 1757 DM_restriction = 0x02 #<<< Derivation by restriction 1758 1759 _DM_Map = { 'extension' : DM_extension 1760 , 'restriction' : DM_restriction } 1761 1762 # How the type was derived (a DM_* value) 1763 # (This field is used to identify unresolved definitions.) 1764 __derivationMethod = None
1765 - def derivationMethod (self):
1766 """How the type was derived.""" 1767 return self.__derivationMethod
1768 1769 # Derived from the final and finalDefault attributes 1770 __final = DM_empty 1771 1772 # Derived from the abstract attribute 1773 __abstract = False
1774 - def abstract (self): return self.__abstract
1775 1776 # A frozenset() of AttributeUse instances. 1777 __attributeUses = None
1778 - def attributeUses (self):
1779 """A frozenset() of AttributeUse instances.""" 1780 return self.__attributeUses
1781 1782 # A map from NCNames to AttributeDeclaration instances that are 1783 # local to this type. 1784 __scopedAttributeDeclarations = None
1785 - def lookupScopedAttributeDeclaration (self, expanded_name):
1786 """Find an attribute declaration with the given name that is local to this type. 1787 1788 Returns None if there is no such local attribute declaration.""" 1789 if self.__scopedAttributeDeclarations is None: 1790 return None 1791 return self.__scopedAttributeDeclarations.get(expanded_name)
1792 1793 # A map from NCNames to ElementDeclaration instances that are 1794 # local to this type. 1795 __scopedElementDeclarations = None
1796 - def lookupScopedElementDeclaration (self, expanded_name):
1797 """Find an element declaration with the given name that is local to this type. 1798 1799 Returns None if there is no such local element declaration.""" 1800 if self.__scopedElementDeclarations is None: 1801 return None 1802 return self.__scopedElementDeclarations.get(expanded_name)
1803 1804 __localScopedDeclarations = None
1805 - def localScopedDeclarations (self, reset=False):
1806 """Return a list of element and attribute declarations that were 1807 introduced in this definition (i.e., their scope is this CTD). 1808 1809 @note: This specifically returns a list, with element declarations 1810 first, because name binding should privilege the elements over the 1811 attributes. Within elements and attributes, the components are sorted 1812 by expanded name, to ensure consistency across a series of binding 1813 generations. 1814 1815 @keyword reset: If C{False} (default), a cached previous value (if it 1816 exists) will be returned. 1817 """ 1818 if reset or (self.__localScopedDeclarations is None): 1819 rve = [ _ed for _ed in self.__scopedElementDeclarations.values() if (self == _ed.scope()) ] 1820 rve.sort(lambda _a, _b: cmp(_a.expandedName(), _b.expandedName())) 1821 rva = [ _ad for _ad in self.__scopedAttributeDeclarations.values() if (self == _ad.scope()) ] 1822 rva.sort(lambda _a, _b: cmp(_a.expandedName(), _b.expandedName())) 1823 self.__localScopedDeclarations = rve 1824 self.__localScopedDeclarations.extend(rva) 1825 return self.__localScopedDeclarations
1826
1827 - def _recordLocalDeclaration (self, decl):
1828 """Record the given declaration as being locally scoped in 1829 this type.""" 1830 assert isinstance(decl, _ScopedDeclaration_mixin) 1831 if isinstance(decl, ElementDeclaration): 1832 scope_map = self.__scopedElementDeclarations 1833 elif isinstance(decl, AttributeDeclaration): 1834 scope_map = self.__scopedAttributeDeclarations 1835 else: 1836 raise pyxb.LogicError('Unexpected instance of %s recording as local declaration' % (type(decl),)) 1837 decl_en = decl.expandedName() 1838 existing_decl = scope_map.setdefault(decl_en, decl) 1839 if decl != existing_decl: 1840 if isinstance(decl, ElementDeclaration): 1841 # Test cos-element-consistent 1842 existing_type = existing_decl.typeDefinition() 1843 pending_type = decl.typeDefinition() 1844 if not pending_type.isDerivationConsistent(existing_type): 1845 raise pyxb.SchemaValidationError('Conflicting element declarations for %s: existing %s versus new %s' % (decl.expandedName(), existing_type, pending_type)) 1846 elif isinstance(decl, AttributeDeclaration): 1847 raise pyxb.SchemaValidationError('Multiple attribute declarations for %s' % (decl.expandedName(),)) 1848 else: 1849 assert False, 'Unrecognized type %s' % (type(decl),) 1850 decl._baseDeclaration(existing_decl) 1851 return self
1852
1853 - def _isHierarchyRoot (self):
1854 """Return C{True} iff this is the root of a complex type definition hierarchy. 1855 """ 1856 base = self.__baseTypeDefinition 1857 return isinstance(base, SimpleTypeDefinition) or base.isUrTypeDefinition()
1858 1859 CT_EMPTY = 'EMPTY' #<<< No content 1860 CT_SIMPLE = 'SIMPLE' #<<< Simple (character) content 1861 CT_MIXED = 'MIXED' #<<< Children may be elements or other (e.g., character) content 1862 CT_ELEMENT_ONLY = 'ELEMENT_ONLY' #<<< Expect only element content. 1863
1864 - def _contentTypeTag (self):
1865 """Return the value of the content type identifier, i.e. one of the 1866 CT_ constants. Return value is None if no content type has been 1867 defined.""" 1868 if isinstance(self.__contentType, tuple): 1869 return self.__contentType[0] 1870 return self.__contentType
1871
1872 - def _contentTypeComponent (self):
1873 if isinstance(self.__contentType, tuple): 1874 return self.__contentType[1] 1875 return None
1876 1877 # Identify the sort of content in this type. 1878 __contentType = None
1879 - def contentType (self):
1880 """Identify the sort of content in this type. 1881 1882 Valid values are: 1883 - C{CT_EMPTY} 1884 - ( C{CT_SIMPLE}, a L{SimpleTypeDefinition} instance ) 1885 - ( C{CT_MIXED}, a L{Particle} instance ) 1886 - ( C{CT_ELEMENT_ONLY}, a L{Particle} instance ) 1887 """ 1888 return self.__contentType
1889
1890 - def contentTypeAsString (self):
1891 if self.CT_EMPTY == self.contentType(): 1892 return 'EMPTY' 1893 ( tag, particle ) = self.contentType() 1894 if self.CT_SIMPLE == tag: 1895 return 'Simple [%s]' % (particle,) 1896 if self.CT_MIXED == tag: 1897 return 'Mixed [%s]' % (particle,) 1898 if self.CT_ELEMENT_ONLY == tag: 1899 return 'Element [%s]' % (particle,) 1900 raise pyxb.LogicError('Unhandled content type')
1901 1902 # Derived from the block and blockDefault attributes 1903 __prohibitedSubstitutions = DM_empty 1904 1905 # @todo: Extracted from children of various types 1906 __annotations = None 1907
1908 - def __init__ (self, *args, **kw):
1909 super(ComplexTypeDefinition, self).__init__(*args, **kw) 1910 self.__derivationMethod = kw.get('derivation_method') 1911 self.__scopedElementDeclarations = { } 1912 self.__scopedAttributeDeclarations = { }
1913
1914 - def hasWildcardElement (self):
1915 """Return True iff this type includes a wildcard element in 1916 its content model.""" 1917 if self.CT_EMPTY == self.contentType(): 1918 return False 1919 ( tag, particle ) = self.contentType() 1920 if self.CT_SIMPLE == tag: 1921 return False 1922 return particle.hasWildcardElement()
1923
1924 - def _updateFromOther_csc (self, other):
1925 """Override fields in this instance with those from the other. 1926 1927 This method is invoked only by Schema._addNamedComponent, and 1928 then only when a built-in type collides with a schema-defined 1929 type. Material like facets is not (currently) held in the 1930 built-in copy, so the DOM information is copied over to the 1931 built-in STD, which is subsequently re-resolved. 1932 1933 Returns self. 1934 """ 1935 assert self != other 1936 assert self.isNameEquivalent(other) 1937 super(ComplexTypeDefinition, self)._updateFromOther_csc(other) 1938 1939 if not other.isResolved(): 1940 if pyxb.namespace.BuiltInObjectUID != self._objectOrigin().generationUID(): 1941 self.__derivationMethod = None 1942 1943 return self
1944 1945 __UrTypeDefinition = None 1946 @classmethod
1947 - def UrTypeDefinition (cls, schema=None, in_builtin_definition=False):
1948 """Create the ComplexTypeDefinition instance that approximates 1949 the ur-type. 1950 1951 See section 3.4.7. 1952 """ 1953 1954 # The first time, and only the first time, this is called, a 1955 # namespace should be provided which is the XMLSchema 1956 # namespace for this run of the system. Please, do not try to 1957 # allow this by clearing the type definition. 1958 #if in_builtin_definition and (cls.__UrTypeDefinition is not None): 1959 # raise pyxb.LogicError('Multiple definitions of UrType') 1960 if cls.__UrTypeDefinition is None: 1961 # NOTE: We use a singleton subclass of this class 1962 assert schema is not None 1963 1964 ns_ctx = schema.targetNamespace().initialNamespaceContext() 1965 1966 kw = { 'name' : 'anyType', 1967 'schema' : schema, 1968 'namespace_context' : ns_ctx, 1969 'binding_namespace' : schema.targetNamespace(), 1970 'derivation_method' : cls.DM_restriction, 1971 'scope' : _ScopedDeclaration_mixin.SCOPE_global } 1972 bi = _UrTypeDefinition(**kw) 1973 1974 # The ur-type is its own baseTypeDefinition 1975 bi.__baseTypeDefinition = bi 1976 1977 # No constraints on attributes 1978 bi._setAttributeWildcard(Wildcard(namespace_constraint=Wildcard.NC_any, process_contents=Wildcard.PC_lax, **kw)) 1979 1980 # There isn't anything to look up, but context is still global. 1981 # No declarations will be created, so use indeterminate scope to 1982 # be consistent with validity checks in Particle constructor. 1983 # Content is mixed, with elements completely unconstrained. @todo: 1984 # not associated with a schema (it should be) 1985 kw = { 'namespace_context' : ns_ctx 1986 , 'schema' : schema 1987 , 'scope': _ScopedDeclaration_mixin.XSCOPE_indeterminate } 1988 w = Wildcard(namespace_constraint=Wildcard.NC_any, process_contents=Wildcard.PC_lax, **kw) 1989 p = Particle(w, min_occurs=0, max_occurs=None, **kw) 1990 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[ p ], **kw) 1991 bi.__contentType = ( cls.CT_MIXED, Particle(m, **kw) ) 1992 1993 # No attribute uses 1994 bi.__attributeUses = set() 1995 1996 # No constraints on extension or substitution 1997 bi.__final = cls.DM_empty 1998 bi.__prohibitedSubstitutions = cls.DM_empty 1999 2000 bi.__abstract = False 2001 2002 # Refer to it by name 2003 bi.setNameInBinding(bi.name()) 2004 2005 # The ur-type is always resolved 2006 bi.__derivationMethod = cls.DM_restriction 2007 2008 cls.__UrTypeDefinition = bi 2009 return cls.__UrTypeDefinition
2010
2011 - def isBuiltin (self):
2012 """Indicate whether this simple type is a built-in type.""" 2013 return (self.UrTypeDefinition() == self)
2014 2015 # bR:CTD
2016 - def _bindingRequires_vx (self, include_lax):
2017 """Complex type definitions depend on their base type definition, the 2018 type definitions of any local attribute declarations, and if strict 2019 the type definitions of any local element declarations.""" 2020 rv = set() 2021 assert self.__baseTypeDefinition is not None 2022 rv.add(self.__baseTypeDefinition) 2023 for decl in self.localScopedDeclarations(): 2024 if include_lax or isinstance(decl, AttributeDeclaration): 2025 rv.add(decl.typeDefinition()) 2026 if include_lax: 2027 ct = self._contentTypeComponent() 2028 if ct is not None: 2029 rv.add(ct) 2030 return frozenset(rv)
2031 2032 # CFD:CTD CFD:ComplexTypeDefinition 2033 @classmethod
2034 - def CreateFromDOM (cls, node, **kw):
2035 # Node should be an XMLSchema complexType node 2036 assert xsd.nodeIsNamed(node, 'complexType') 2037 2038 name = NodeAttribute(node, 'name') 2039 2040 rv = cls(name=name, node=node, derivation_method=None, **kw) 2041 2042 if name is None: 2043 assert not isinstance(rv.owner(), Schema) 2044 2045 # Most of the time, the scope will be global. It can be something 2046 # else only if this is an anonymous CTD (created within an element 2047 # declaration which itself may be global, in a containing CTD, or in a 2048 # model group). 2049 if not (rv._scopeIsGlobal() or rv.isAnonymous()): 2050 raise pyxb.LogicError('Attempt to create non-global complex type definition') 2051 2052 kw.pop('node', None) 2053 kw['owner'] = rv 2054 kw['scope'] = rv 2055 2056 return rv.__setContentFromDOM(node, **kw)
2057 2058 __ckw = None 2059 __anyAttribute = None 2060 __attributeGroupAttributes = None 2061 __usesC1 = None 2062 __usesC1C2 = None 2063 __attributeGroups = None 2064 __PrivateTransient.update(['ckw', 'anyAttribute', 'attributeGroupAttributes', 'usesC1', 'usesC1C2', 'attributeGroups' ]) 2065 2066 # Handle attributeUses, attributeWildcard, contentType
2067 - def __completeProcessing (self, method, content_style):
2068 2069 if self.__usesC1C2 is None: 2070 # Handle clauses 1 and 2 (common between simple and complex types) 2071 uses_c1 = self.__usesC1 # attribute children 2072 uses_c2 = set() # attribute group children 2073 self.__attributeGroups = [] 2074 for ag_attr in self.__attributeGroupAttributes: 2075 ag_en = self._namespaceContext().interpretQName(ag_attr) 2076 agd = ag_en.attributeGroupDefinition() 2077 if agd is None: 2078 raise pyxb.SchemaValidationError('Attribute group %s cannot be found' % (ag_en,)) 2079 if not agd.isResolved(): 2080 self._queueForResolution('unresolved attribute group') 2081 return self 2082 self.__attributeGroups.append(agd) 2083 uses_c2.update(agd.attributeUses()) 2084 2085 uses_c1c2 = uses_c1.union(uses_c2) 2086 for au in uses_c1c2: 2087 if not au.isResolved(): 2088 self._queueForResolution('attribute use not resolved') 2089 return self 2090 ad_en = au.attributeDeclaration().expandedName() 2091 if not au.attributeDeclaration().isResolved(): 2092 self._queueForResolution('unresolved attribute declaration %s from base type' % (ad_en,)) 2093 return self 2094 2095 self.__usesC1C2 = frozenset([ _u._adaptForScope(self) for _u in uses_c1c2 ]) 2096 2097 # Handle clause 3. Note the slight difference in description between 2098 # simple and complex content is just that the complex content doesn't 2099 # bother to check that the base type definition is a complex type 2100 # definition. So the same code should work for both, and we don't 2101 # bother to check content_style. 2102 uses_c3 = set() # base attributes 2103 if isinstance(self.__baseTypeDefinition, ComplexTypeDefinition): 2104 # NB: The base type definition should be resolved, which means 2105 # that all its attribute uses have been adapted for scope already 2106 uses_c3 = set(self.__baseTypeDefinition.__attributeUses) 2107 assert self.__baseTypeDefinition.isResolved() 2108 for au in uses_c3: 2109 if not au.isResolved(): 2110 self._queueForResolution('unresolved attribute use from base type') 2111 return self 2112 ad_en = au.attributeDeclaration().expandedName() 2113 if not au.attributeDeclaration().isResolved(): 2114 self._queueForResolution('unresolved attribute declaration %s from base type' % (ad_en,)) 2115 return self 2116 assert not au.attributeDeclaration()._scopeIsIndeterminate() 2117 2118 if self.DM_restriction == method: 2119 # Exclude attributes per clause 3. Note that this process 2120 # handles both 3.1 and 3.2, since we have not yet filtered 2121 # uses_c1 for prohibited attributes. 2122 for au in self.__usesC1C2: 2123 matching_uses = au.matchingQNameMembers(uses_c3) 2124 assert matching_uses is not None 2125 assert 1 >= len(matching_uses), 'Multiple inherited attribute uses with name %s' 2126 for au2 in matching_uses: 2127 assert au2.isResolved() 2128 uses_c3.remove(au2) 2129 au._setRestrictionOf(au2) 2130 else: 2131 # In theory, the same attribute name can't appear in the base 2132 # and sub types because that would violate the local 2133 # declaration constraint. 2134 assert self.DM_extension == method 2135 2136 use_map = { } 2137 for au in self.__usesC1C2.union(uses_c3): 2138 assert au.isResolved() 2139 ad_en = au.attributeDeclaration().expandedName() 2140 if ad_en in use_map: 2141 raise pyxb.SchemaValidationError('Multiple definitions for %s in CTD %s' % (ad_en, self.expandedName())) 2142 use_map[ad_en] = au 2143 2144 # Past the last point where we might not resolve this instance. Store 2145 # the attribute uses, also recording local attribute declarations. 2146 self.__attributeUses = frozenset(use_map.values()) 2147 if not self._scopeIsIndeterminate(): 2148 for au in self.__attributeUses: 2149 assert not au.attributeDeclaration()._scopeIsIndeterminate(), 'indeterminate scope for %s' % (au,) 2150 2151 # @todo: Handle attributeWildcard 2152 # Clause 1 2153 local_wildcard = None 2154 if self.__anyAttribute is not None: 2155 local_wildcard = Wildcard.CreateFromDOM(self.__anyAttribute) 2156 2157 # Clause 2 2158 complete_wildcard = _AttributeWildcard_mixin.CompleteWildcard(self._namespaceContext(), self.__attributeGroups, local_wildcard) 2159 2160 # Clause 3 2161 if self.DM_restriction == method: 2162 # Clause 3.1 2163 self._setAttributeWildcard(complete_wildcard) 2164 else: 2165 assert (self.DM_extension == method) 2166 assert self.baseTypeDefinition().isResolved() 2167 # 3.2.1 2168 base_wildcard = None 2169 if isinstance(self.baseTypeDefinition(), ComplexTypeDefinition): 2170 base_wildcard = self.baseTypeDefinition().attributeWildcard() 2171 # 3.2.2 2172 if base_wildcard is not None: 2173 if complete_wildcard is None: 2174 # 3.2.2.1.1 2175 self._setAttributeWildcard(base_wildcard) 2176 else: 2177 # 3.2.2.1.2 2178 self._setAttributeWildcard(process_contents=complete_wildcard.processContents(), 2179 namespace_constraint = Wildcard.IntensionalUnion([complete_wildcard.namespaceConstraint(), 2180 base_wildcard.namespaceConstraint()]), 2181 annotation=complete_wildcard.annotation()) 2182 else: 2183 # 3.2.2.2 2184 self._setAttributeWildcard(complete_wildcard) 2185 2186 # @todo: Make sure we didn't miss any child nodes 2187 2188 # Remove local attributes we will never use again 2189 del self.__usesC1 2190 del self.__usesC1C2 2191 del self.__attributeGroups 2192 self.__ckw = None 2193 2194 # Only now that we've succeeded do we store the method, which 2195 # marks this component resolved. 2196 2197 self.__derivationMethod = method 2198 return self
2199
2200 - def __simpleContent (self, method, **kw):
2201 # Do content type 2202 if isinstance(self.__baseTypeDefinition, ComplexTypeDefinition): 2203 # Clauses 1, 2, and 3 might apply 2204 parent_content_type = self.__baseTypeDefinition.__contentType 2205 #print '%s %s %s' % (self.expandedName(), self.__baseTypeDefinition.expandedName(), parent_content_type) 2206 if ((type(parent_content_type) == tuple) \ 2207 and (self.CT_SIMPLE == parent_content_type[0]) \ 2208 and (self.DM_restriction == method)): 2209 # Clause 1 2210 assert self.__ctscRestrictionNode is not None 2211 std = self.__ctscClause2STD 2212 if std is None: 2213 std = parent_content_type[1] 2214 assert isinstance(std, SimpleTypeDefinition) 2215 if not std.isResolved(): 2216 return None 2217 restriction_node = self.__ctscRestrictionNode 2218 self.__ctscClause2STD = None 2219 self.__ctscRestrictionNode = None 2220 return ( self.CT_SIMPLE, std._createRestriction(self, restriction_node) ) 2221 elif ((type(parent_content_type) == tuple) \ 2222 and (self.CT_MIXED == parent_content_type[0]) \ 2223 and parent_content_type[1].isEmptiable()): 2224 # Clause 2 2225 assert isinstance(self.__ctscClause2STD, SimpleTypeDefinition) 2226 return ( self.CT_SIMPLE, self.__ctscClause2STD ) 2227 else: 2228 # Clause 3 2229 return parent_content_type 2230 else: 2231 # Clause 4 2232 return ( self.CT_SIMPLE, self.__baseTypeDefinition ) 2233 assert False
2234 2235 __ctscClause2STD = None 2236 __ctscRestrictioNode = None 2237
2238 - def __setComplexContentFromDOM (self, type_node, content_node, definition_node_list, method, **kw):
2239 # Do content type. Cache the keywords that need to be used 2240 # for newly created schema components. 2241 ckw = kw.copy() 2242 ckw['namespace_context'] = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(type_node) 2243 2244 # Definition 1: effective mixed 2245 mixed_attr = None 2246 if content_node is not None: 2247 mixed_attr = NodeAttribute(content_node, 'mixed') 2248 if mixed_attr is None: 2249 mixed_attr = NodeAttribute(type_node, 'mixed') 2250 if mixed_attr is not None: 2251 effective_mixed = datatypes.boolean(mixed_attr) 2252 else: 2253 effective_mixed = False 2254 2255 # Definition 2: effective content 2256 case_2_1_predicate_count = 0 2257 test_2_1_1 = True 2258 test_2_1_2 = False 2259 test_2_1_3 = False 2260 typedef_node = None 2261 for cn in definition_node_list: 2262 if Node.ELEMENT_NODE != cn.nodeType: 2263 continue 2264 if xsd.nodeIsNamed(cn, 'simpleContent', 'complexContent'): 2265 # Should have found the content node earlier. 2266 raise pyxb.LogicError('Missed explicit wrapper in complexType content') 2267 if Particle.IsTypedefNode(cn): 2268 typedef_node = cn 2269 test_2_1_1 = False 2270 if xsd.nodeIsNamed(cn, 'all', 'sequence') \ 2271 and (not HasNonAnnotationChild(cn)): 2272 test_2_1_2 = True 2273 if xsd.nodeIsNamed(cn, 'choice') \ 2274 and (not HasNonAnnotationChild(cn)): 2275 mo_attr = NodeAttribute(cn, 'minOccurs') 2276 if ((mo_attr is not None) \ 2277 and (0 == datatypes.integer(mo_attr))): 2278 test_2_1_3 = True 2279 satisfied_predicates = 0 2280 if test_2_1_1: 2281 satisfied_predicates += 1 2282 if test_2_1_2: 2283 satisfied_predicates += 1 2284 if test_2_1_3: 2285 satisfied_predicates += 1 2286 if 1 == satisfied_predicates: 2287 if effective_mixed: 2288 # Clause 2.1.4 2289 assert (typedef_node is None) or test_2_1_2 2290 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[], **ckw) 2291 effective_content = Particle(m, **ckw) 2292 else: 2293 # Clause 2.1.5 2294 effective_content = self.CT_EMPTY 2295 else: 2296 # Clause 2.2 2297 assert typedef_node is not None 2298 effective_content = Particle.CreateFromDOM(typedef_node, **kw) 2299 2300 # For issues related to soapenc:Array and the fact that PyXB 2301 # determines the content of types derived from it is empty, see 2302 # http://tech.groups.yahoo.com/group/soapbuilders/message/5879 and 2303 # lament the fact that the WSDL spec is not compatible with XSD. It 2304 # is *not* an error in PyXB. 2305 2306 self.__effectiveMixed = effective_mixed 2307 self.__effectiveContent = effective_content 2308 self.__ckw = ckw
2309 2310 #if isinstance(effective_content, Particle): 2311 # print 'Effective total range: %s %s' % effective_content.effectiveTotalRange() 2312
2313 - def __complexContent (self, method):
2314 ckw = self.__ckw 2315 2316 # Shared from clause 3.1.2 2317 if self.__effectiveMixed: 2318 ct = self.CT_MIXED 2319 else: 2320 ct = self.CT_ELEMENT_ONLY 2321 # Clause 3 2322 if self.DM_restriction == method: 2323 # Clause 3.1 2324 if self.CT_EMPTY == self.__effectiveContent: 2325 # Clause 3.1.1 2326 content_type = self.CT_EMPTY # ASSIGN CT_EMPTY 2327 else: 2328 # Clause 3.1.2(.2) 2329 content_type = ( ct, self.__effectiveContent ) # ASSIGN RESTRICTION 2330 assert 0 == len(self.__scopedElementDeclarations) 2331 # Reference the parent element declarations; normally this 2332 # would happen naturally as a consequence of appending this 2333 # type's content model to the parent's, but with restriction 2334 # there is no such re-use unless we do this. 2335 self.__scopedElementDeclarations.update(self.__baseTypeDefinition.__scopedElementDeclarations) 2336 else: 2337 # Clause 3.2 2338 assert self.DM_extension == method 2339 assert self.__baseTypeDefinition.isResolved() 2340 parent_content_type = self.__baseTypeDefinition.contentType() 2341 if self.CT_EMPTY == self.__effectiveContent: 2342 content_type = parent_content_type # ASSIGN EXTENSION PARENT ONLY 2343 elif self.CT_EMPTY == parent_content_type: 2344 # Clause 3.2.2 2345 content_type = ( ct, self.__effectiveContent ) # ASSIGN EXTENSION LOCAL ONLY 2346 else: 2347 assert type(parent_content_type) == tuple 2348 m = ModelGroup(compositor=ModelGroup.C_SEQUENCE, particles=[ parent_content_type[1], self.__effectiveContent ], **ckw) 2349 content_type = ( ct, Particle(m, **ckw) ) # ASSIGN EXTENSION PARENT AND LOCAL 2350 2351 assert (self.CT_EMPTY == content_type) or ((type(content_type) == tuple) and (content_type[1] is not None)) 2352 return content_type
2353
2354 - def isResolved (self):
2355 """Indicate whether this complex type is fully defined. 2356 2357 All built-in type definitions are resolved upon creation. 2358 Schema-defined type definitionss are held unresolved until the 2359 schema has been completely read, so that references to later 2360 schema-defined types can be resolved. Resolution is performed 2361 after the entire schema has been scanned and type-definition 2362 instances created for all topLevel{Simple,Complex}Types. 2363 2364 If a built-in type definition is also defined in a schema 2365 (which it should be), the built-in definition is kept, with 2366 the schema-related information copied over from the matching 2367 schema-defined type definition. The former then replaces the 2368 latter in the list of type definitions to be resolved. See 2369 Schema._addNamedComponent. 2370 """ 2371 # Only unresolved nodes have an unset derivationMethod 2372 return (self.__derivationMethod is not None)
2373 2374 # Back door to allow the ur-type to re-resolve itself. Only needed when 2375 # we're generating bindings for XMLSchema itself.
2376 - def _setDerivationMethod (self, derivation_method):
2377 self.__derivationMethod = derivation_method 2378 return self
2379
2380 - def __setContentFromDOM (self, node, **kw):
2381 schema = kw.get('schema') 2382 assert schema is not None 2383 self.__prohibitedSubstitutions = schema.blockForNode(node, self._DM_Map) 2384 self.__final = schema.finalForNode(node, self._DM_Map) 2385 2386 attr_val = NodeAttribute(node, 'abstract') 2387 if attr_val is not None: 2388 self.__abstract = datatypes.boolean(attr_val) 2389 2390 # Assume we're in the short-hand case: the entire content is 2391 # implicitly wrapped in a complex restriction of the ur-type. 2392 definition_node_list = node.childNodes 2393 is_complex_content = True 2394 self.__baseTypeDefinition = ComplexTypeDefinition.UrTypeDefinition() 2395 method = self.DM_restriction 2396 2397 # Determine whether above assumption is correct by looking for 2398 # element content and seeing if it's one of the wrapper 2399 # elements. 2400 first_elt = LocateFirstChildElement(node) 2401 content_node = None 2402 clause2_std = None 2403 ctsc_restriction_node = None 2404 if first_elt: 2405 have_content = False 2406 if xsd.nodeIsNamed(first_elt, 'simpleContent'): 2407 have_content = True 2408 is_complex_content = False 2409 elif xsd.nodeIsNamed(first_elt, 'complexContent'): 2410 have_content = True 2411 else: 2412 # Not one of the wrappers; use implicit wrapper around 2413 # the children 2414 if not Particle.IsParticleNode(first_elt, 'attributeGroup', 'attribute', 'anyAttribute'): 2415 raise pyxb.SchemaValidationError('Unexpected element %s at root of complexType' % (first_elt.nodeName,)) 2416 if have_content: 2417 # Repeat the search to verify that only the one child is present. 2418 content_node = LocateFirstChildElement(node, require_unique=True) 2419 assert content_node == first_elt 2420 2421 # Identify the contained restriction or extension 2422 # element, and extract the base type. 2423 ions = LocateFirstChildElement(content_node, absent_ok=False) 2424 if xsd.nodeIsNamed(ions, 'restriction'): 2425 method = self.DM_restriction 2426 if not is_complex_content: 2427 # Clause 2 of complex type with simple content 2428 ctsc_restriction_node = ions 2429 ions_st = LocateUniqueChild(ions,'simpleType') 2430 if ions_st is not None: 2431 clause2_std = SimpleTypeDefinition.CreateFromDOM(ions_st, **kw) 2432 elif xsd.nodeIsNamed(ions, 'extension'): 2433 method = self.DM_extension 2434 else: 2435 raise pyxb.SchemaValidationError('Expected restriction or extension as sole child of %s in %s' % (content_node.nodeName, self.name())) 2436 self.__baseAttribute = NodeAttribute(ions, 'base') 2437 if self.__baseAttribute is None: 2438 raise pyxb.SchemaValidationError('Element %s missing base attribute' % (ions.nodeName,)) 2439 self.__baseTypeDefinition = None 2440 # The content is defined by the restriction/extension element 2441 definition_node_list = ions.childNodes 2442 # deriviationMethod is assigned after resolution completes 2443 self.__pendingDerivationMethod = method 2444 self.__isComplexContent = is_complex_content 2445 self.__ctscRestrictionNode = ctsc_restriction_node 2446 self.__ctscClause2STD = clause2_std 2447 2448 (attributes, attribute_group_attrs, any_attribute) = self._attributeRelevantChildren(definition_node_list) 2449 self.__usesC1 = set() 2450 for cn in attributes: 2451 au = AttributeUse.CreateFromDOM(cn, **kw) 2452 self.__usesC1.add(au) 2453 self.__attributeGroupAttributes = attribute_group_attrs 2454 self.__anyAttribute = any_attribute 2455 2456 if self.__isComplexContent: 2457 self.__setComplexContentFromDOM(node, content_node, definition_node_list, self.__pendingDerivationMethod, **kw) 2458 2459 # Creation does not attempt to do resolution. Queue up the newly created 2460 # whatsis so we can resolve it after everything's been read in. 2461 self._annotationFromDOM(node) 2462 2463 if not self.isResolved(): 2464 self._queueForResolution('creation') 2465 2466 return self
2467 2468 # Resolution of a CTD can be delayed for the following reasons: 2469 # 2470 # * It extends or restricts a base type that has not been resolved 2471 # [_resolve] 2472 # 2473 # * It refers to an attribute or attribute group that has not been 2474 # resolved [__completeProcessing] 2475 # 2476 # * It includes an attribute that matches in NCName and namespace 2477 # an unresolved attribute from the base type 2478 # [__completeProcessing] 2479 # 2480 # * The content model includes a particle which cannot be resolved 2481 # (so has not contributed any local element declarations). 2482 # res:CTD
2483 - def _resolve (self):
2484 if self.isResolved(): 2485 return self 2486 2487 # @todo: implement prohibitedSubstitutions, final, annotations 2488 2489 # See whether we've resolved through to the base type 2490 if self.__baseTypeDefinition is None: 2491 base_en = self._namespaceContext().interpretQName(self.__baseAttribute) 2492 base_type = base_en.typeDefinition() 2493 if base_type is None: 2494 raise pyxb.SchemaValidationError('Cannot locate %s: need import?' % (base_en,)) 2495 if not base_type.isResolved(): 2496 # Have to delay resolution until the type this 2497 # depends on is available. 2498 self._queueForResolution('unresolved base type %s' % (base_en,)) 2499 return self 2500 self.__baseTypeDefinition = base_type 2501 2502 # Only build the content once. This will not complete if the content 2503 # is a restriction of an unresolved simple type; otherwise, it only 2504 # depends on the base type which we know is good. 2505 if self.__contentType is None: 2506 if self.__isComplexContent: 2507 content_type = self.__complexContent(self.__pendingDerivationMethod) 2508 self.__contentStyle = 'complex' 2509 else: 2510 # The definition node list is not relevant to simple content 2511 content_type = self.__simpleContent(self.__pendingDerivationMethod) 2512 if content_type is None: 2513 self._queueForResolution('restriction of unresolved simple type') 2514 return self 2515 self.__contentStyle = 'simple' 2516 assert content_type is not None 2517 self.__contentType = content_type 2518 2519 # Last chance for failure is if we haven't been able to 2520 # extract all the element declarations that might appear in 2521 # this complex type. That technically wouldn't stop this from 2522 # being resolved, but it does prevent us from using it as a 2523 # context. 2524 if isinstance(self.__contentType, tuple) and isinstance(self.__contentType[1], Particle): 2525 prt = self.__contentType[1] 2526 if not prt.isAdaptable(self): 2527 self._queueForResolution('content particle %s is not deep-resolved' % (prt,)) 2528 return self 2529 self.__contentType = (self.__contentType[0], prt._adaptForScope(self, self)) 2530 #print 'Done adapting %s content' % (self.expandedName(),) 2531 2532 return self.__completeProcessing(self.__pendingDerivationMethod, self.__contentStyle)
2533
2534 - def pythonSupport (self):
2535 """Complex type definitions have no built-in type support.""" 2536 return None
2537
2538 - def __str__ (self):
2539 if self.isAnonymous(): 2540 return 'CTD{Anonymous}[%x]' % (id(self),) 2541 return 'CTD[%s]' % (self.expandedName(),)
2542
2543 -class _UrTypeDefinition (ComplexTypeDefinition, _Singleton_mixin):
2544 """Subclass ensures there is only one ur-type."""
2545 - def pythonSupport (self):
2546 """The ur-type does have a Python class backing it up.""" 2547 return datatypes.anyType
2548
2549 - def _resolve (self):
2550 # The ur type is always resolved, except when it gets unresolved 2551 # through being updated from an instance read from the schema. 2552 return self._setDerivationMethod(self.DM_restriction)
2553
2554 2555 -class AttributeGroupDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin, _AttributeWildcard_mixin):
2556 """An XMLSchema U{Attribute Group Definition<http://www.w3.org/TR/xmlschema-1/#cAttribute_Group_Definitions>} component.""" 2557 __PrivateTransient = set() 2558 2559 # A frozenset of AttributeUse instances 2560 __attributeUses = None 2561
2562 - def __init__ (self, *args, **kw):
2563 super(AttributeGroupDefinition, self).__init__(*args, **kw)
2564 #assert 'scope' in kw 2565 #assert self._scopeIsIndeterminate() 2566
2567 - def __str__ (self):
2568 return 'AGD[%s]' % (self.expandedName(),)
2569 2570 @classmethod
2571 - def CreateBaseInstance (cls, name, schema, attribute_uses):
2572 """Create an attribute declaration component for a specified namespace.""" 2573 kw = { 'name' : name, 2574 'schema' : schema, 2575 'namespace_context' : schema.targetNamespace().initialNamespaceContext(), 2576 'scope' : _ScopedDeclaration_mixin.SCOPE_global } 2577 bi = cls(**kw) 2578 bi.__attributeUses = frozenset(attribute_uses) 2579 bi.__isResolved = True 2580 return bi
2581 2582 __anyAttribute = None 2583 __attributeGroupAttributes = None 2584 __PrivateTransient.update(['anyAttribute', 'attributeGroupAttributes']) 2585 2586 # CFD:AGD CFD:AttributeGroupDefinition 2587 @classmethod
2588 - def CreateFromDOM (cls, node, **kw):
2589 """Create an attribute group definition from the given DOM node. 2590 2591 """ 2592 2593 assert xsd.nodeIsNamed(node, 'attributeGroup') 2594 name = NodeAttribute(node, 'name') 2595 schema = kw['schema'] 2596 2597 # Attribute group definitions can only appear at the top level of the 2598 # schema, and any definitions in them are scope indeterminate until 2599 # they're referenced in a complex type. 2600 kw.update({ 'scope' : _ScopedDeclaration_mixin.XSCOPE_indeterminate }) 2601 rv = cls(name=name, node=node, **kw) 2602 2603 rv._annotationFromDOM(node) 2604 2605 # Attribute group definitions must not be references 2606 rv.__refAttribute = NodeAttribute(node, 'ref') 2607 if rv.__refAttribute is not None: 2608 raise pyxb.SchemaValidationError('Attribute reference at top level') 2609 2610 kw.pop('node', None) 2611 kw['owner'] = rv 2612 2613 (attributes, attribute_group_attrs, any_attribute) = rv._attributeRelevantChildren(node.childNodes) 2614 rv.__attributeUses = set() 2615 for cn in attributes: 2616 rv.__attributeUses.add(AttributeUse.CreateFromDOM(cn, **kw)) 2617 rv.__attributeGroupAttributes = attribute_group_attrs 2618 rv.__anyAttribute = any_attribute 2619 2620 # Unconditionally queue for resolution, to avoid repeating the 2621 # wildcard code. 2622 rv._queueForResolution('creation') 2623 2624 return rv
2625 2626 # Indicates whether we have resolved any references 2627 __isResolved = False
2628 - def isResolved (self):
2629 return self.__isResolved
2630
2631 - def _resolve (self):
2632 if self.__isResolved: 2633 return self 2634 2635 uses = self.__attributeUses 2636 attribute_groups = [] 2637 for ag_attr in self.__attributeGroupAttributes: 2638 ag_en = self._namespaceContext().interpretQName(ag_attr) 2639 agd = ag_en.attributeGroupDefinition() 2640 if agd is None: 2641 raise pyxb.SchemaValidationError('Attribute group %s cannot be found' % (ag_en,)) 2642 attribute_groups.append(agd) 2643 uses = uses.union(agd.attributeUses()) 2644 2645 self.__attributeUses = frozenset(uses) 2646 2647 # "Complete wildcard" per CTD 2648 local_wildcard = None 2649 if self.__anyAttribute is not None: 2650 local_wildcard = Wildcard.CreateFromDOM(self.__anyAttribute) 2651 self._setAttributeWildcard(_AttributeWildcard_mixin.CompleteWildcard(self._namespaceContext(), attribute_groups, local_wildcard)) 2652 2653 self.__isResolved = True 2654 return self
2655 2656 # bR:AGD
2657 - def _bindingRequires_vx (self, include_lax):
2658 """Attribute group declarations require their uses, but only if lax.""" 2659 if not include_lax: 2660 return frozenset() 2661 return frozenset(self.attributeUses())
2662
2663 - def attributeUses (self):
2664 return self.__attributeUses
2665
2666 -class ModelGroupDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, _Annotated_mixin):
2667 """An XMLSchema U{Model Group Definition<http://www.w3.org/TR/xmlschema-1/#cModel_Group_Definitions>} component.""" 2668 # Reference to a _ModelGroup 2669 __modelGroup = None 2670
2671 - def modelGroup (self):
2672 """The model group for which this definition provides a name.""" 2673 return self.__modelGroup
2674 2675 # CFD:MGD CFD:ModelGroupDefinition 2676 @classmethod
2677 - def CreateFromDOM (cls, node, **kw):
2678 """Create a Model Group Definition from a DOM element node. 2679 2680 wxs is a Schema instance within which the model group is being 2681 defined. 2682 2683 node is a DOM element. The name must be 'group', and the node 2684 must be in the XMLSchema namespace. The node must have a 2685 'name' attribute, and must not have a 'ref' attribute. 2686 """ 2687 assert xsd.nodeIsNamed(node, 'group') 2688 2689 assert NodeAttribute(node, 'ref') is None 2690 2691 name = NodeAttribute(node, 'name') 2692 kw['scope'] = _ScopedDeclaration_mixin.XSCOPE_indeterminate 2693 rv = cls(name=name, node=node, **kw) 2694 rv._annotationFromDOM(node) 2695 2696 kw.pop('node', None) 2697 kw['owner'] = rv 2698 2699 for cn in node.childNodes: 2700 if Node.ELEMENT_NODE != cn.nodeType: 2701 continue 2702 if ModelGroup.IsGroupMemberNode(cn): 2703 assert not rv.__modelGroup 2704 # Model group definitions always occur at the top level of the 2705 # schema, so the elements declared in them are not bound to a 2706 # scope until they are referenced in a complex type. 2707 rv.__modelGroup = ModelGroup.CreateFromDOM(cn, model_group_definition=rv, **kw) 2708 assert rv.__modelGroup is not None 2709 return rv
2710 2711 # bR:MGD
2712 - def _bindingRequires_vx (self, include_lax):
2713 """Model group definitions depend on the contained model group.""" 2714 if not include_lax: 2715 return frozenset() 2716 return frozenset([self.__modelGroup])
2717
2718 - def __str__ (self):
2719 return 'MGD[%s: %s]' % (self.name(), self.modelGroup())
2720
2721 2722 -class ModelGroup (_SchemaComponent_mixin, _Annotated_mixin):
2723 """An XMLSchema U{Model Group<http://www.w3.org/TR/xmlschema-1/#cModel_Group>} component.""" 2724 C_INVALID = 0 2725 C_ALL = 0x01 2726 C_CHOICE = 0x02 2727 C_SEQUENCE = 0x03 2728 2729 # One of the C_* values above. Set at construction time from the 2730 # keyword parameter "compositor". 2731 __compositor = C_INVALID
2732 - def compositor (self): return self.__compositor
2733 2734 @classmethod
2735 - def CompositorToString (cls, compositor):
2736 """Map a compositor value to a string.""" 2737 if cls.C_ALL == compositor: 2738 return 'all' 2739 if cls.C_CHOICE == compositor: 2740 return 'choice' 2741 if cls.C_SEQUENCE == compositor: 2742 return 'sequence' 2743 return 'invalid'
2744
2745 - def compositorToString (self):
2746 """Return a string representing the compositor value.""" 2747 return self.CompositorToString(self.__compositor)
2748 2749 # A list of Particle instances. Set at construction time from 2750 # the keyword parameter "particles". 2751 __particles = None
2752 - def particles (self): return self.__particles
2753
2754 - def isAdaptable (self, ctd):
2755 """A model group has an unresolvable particle if any of its 2756 particles is unresolvable. Duh.""" 2757 for p in self.particles(): 2758 if not p.isAdaptable(ctd): 2759 return False 2760 return True
2761
2762 - def effectiveTotalRange (self, particle):
2763 """Return the minimum and maximum of the number of elements that can 2764 appear in a sequence matched by this particle. 2765 2766 See http://www.w3.org/TR/xmlschema-1/#cos-seq-range 2767 """ 2768 if self.__compositor in (self.C_ALL, self.C_SEQUENCE): 2769 sum_minoccurs = 0 2770 sum_maxoccurs = 0 2771 for prt in self.__particles: 2772 (prt_min, prt_max) = prt.effectiveTotalRange() 2773 sum_minoccurs += prt_min 2774 if sum_maxoccurs is not None: 2775 if prt_max is None: 2776 sum_maxoccurs = None 2777 else: 2778 sum_maxoccurs += prt_max 2779 prod_maxoccurs = particle.maxOccurs() 2780 if prod_maxoccurs is not None: 2781 if sum_maxoccurs is None: 2782 prod_maxoccurs = None 2783 else: 2784 prod_maxoccurs *= sum_maxoccurs 2785 return (sum_minoccurs * particle.minOccurs(), prod_maxoccurs) 2786 assert self.__compositor == self.C_CHOICE 2787 if 0 == len(self.__particles): 2788 min_minoccurs = 0 2789 max_maxoccurs = 0 2790 else: 2791 (min_minoccurs, max_maxoccurs) = self.__particles[0].effectiveTotalRange() 2792 for prt in self.__particles[1:]: 2793 (prt_min, prt_max) = prt.effectiveTotalRange() 2794 if prt_min < min_minoccurs: 2795 min_minoccurs = prt_min 2796 if prt_max is None: 2797 max_maxoccurs = None 2798 elif (max_maxoccurs is not None) and (prt_max > max_maxoccurs): 2799 max_maxoccurs = prt_max 2800 min_minoccurs *= particle.minOccurs() 2801 if (max_maxoccurs is not None) and (particle.maxOccurs() is not None): 2802 max_maxoccurs *= particle.maxOccurs() 2803 return (min_minoccurs, max_maxoccurs)
2804 2805 # The ModelGroupDefinition that names this ModelGroup, or None if 2806 # the ModelGroup is anonymous. This is set at construction time 2807 # from the keyword parameter "model_group_definition". 2808 __modelGroupDefinition = None
2809 - def modelGroupDefinition (self):
2810 """The ModelGroupDefinition that names this group, or None if it is unnamed.""" 2811 return self.__modelGroupDefinition
2812
2813 - def __init__ (self, compositor, particles, *args, **kw):
2814 """Create a new model group. 2815 2816 compositor must be a legal compositor value (one of C_ALL, C_CHOICE, C_SEQUENCE). 2817 2818 particles must be a list of zero or more Particle instances. 2819 2820 scope is the _ScopeDeclaration_mixin context into which new 2821 declarations are recorded. It can be SCOPE_global, a complex 2822 type definition, or None if this is (or is within) a named 2823 model group. 2824 2825 model_group_definition is an instance of ModelGroupDefinition 2826 if this is a named model group. It defaults to None 2827 indicating a local group. 2828 """ 2829 2830 super(ModelGroup, self).__init__(*args, **kw) 2831 assert 'scope' in kw 2832 self.__compositor = compositor 2833 #print 'Incoming particles %s with scope %s' % (particles, self._scope()) 2834 self.__particles = particles 2835 self.__modelGroupDefinition = kw.get('model_group_definition')
2836
2837 - def pluralityData (self):
2838 """Get the plurality data for this model group. 2839 """ 2840 return _PluralityData(self)
2841
2842 - def hasWildcardElement (self):
2843 """Return True if the model includes a wildcard amongst its particles.""" 2844 for p in self.particles(): 2845 if p.hasWildcardElement(): 2846 return True 2847 return False
2848 2849 # bR:MG
2850 - def _bindingRequires_vx (self, include_lax):
2851 if not include_lax: 2852 return frozenset() 2853 return frozenset(self.__particles)
2854 2855 # CFD:MG CFD:ModelGroup 2856 @classmethod
2857 - def CreateFromDOM (cls, node, **kw):
2858 """Create a model group from the given DOM node. 2859 2860 wxs is a Schema instance within which the model group is being 2861 defined. 2862 2863 node is a DOM element. The name must be one of ( 'all', 2864 'choice', 'sequence' ), and the node must be in the XMLSchema 2865 namespace. 2866 2867 scope is the _ScopeDeclaration_mxin context that is assigned 2868 to declarations that appear within the model group. It can be 2869 None, indicating no scope defined, or a complex type 2870 definition. 2871 """ 2872 2873 scope = kw['scope'] 2874 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition) 2875 2876 if xsd.nodeIsNamed(node, 'all'): 2877 compositor = cls.C_ALL 2878 elif xsd.nodeIsNamed(node, 'choice'): 2879 compositor = cls.C_CHOICE 2880 elif xsd.nodeIsNamed(node, 'sequence'): 2881 compositor = cls.C_SEQUENCE 2882 else: 2883 raise pyxb.IncompleteImplementationError('ModelGroup: Got unexpected %s' % (node.nodeName,)) 2884 particles = [] 2885 # Remove the owner from particle constructor arguments: we need to set it later 2886 kw.pop('owner', None) 2887 for cn in node.childNodes: 2888 if Node.ELEMENT_NODE != cn.nodeType: 2889 continue 2890 if Particle.IsParticleNode(cn): 2891 # NB: Ancestor of particle is set in the ModelGroup constructor 2892 particles.append(Particle.CreateFromDOM(node=cn, **kw)) 2893 elif not xsd.nodeIsNamed(cn, 'annotation'): 2894 raise pyxb.SchemaValidationError('Unexpected element %s in model group' % (cn.nodeName,)) 2895 rv = cls(compositor, particles, node=node, **kw) 2896 for p in particles: 2897 p._setOwner(rv) 2898 rv._annotationFromDOM(node) 2899 return rv
2900 2901 @classmethod
2902 - def IsGroupMemberNode (cls, node):
2903 return xsd.nodeIsNamed(node, 'all', 'choice', 'sequence')
2904
2905 - def elementDeclarations (self):
2906 """Return a list of all ElementDeclarations that are at the 2907 top level of this model group, in the order in which they can 2908 occur.""" 2909 element_decls = [] 2910 model_groups = [ self ] 2911 #print 'Extracting element declarations from model group with %d particles: %s' % (len(self.particles()), self.particles()) 2912 while model_groups: 2913 mg = model_groups.pop(0) 2914 for p in mg.particles(): 2915 if isinstance(p.term(), ModelGroup): 2916 model_groups.append(p.term()) 2917 elif isinstance(p.term(), ElementDeclaration): 2918 element_decls.extend(p.elementDeclarations()) 2919 else: 2920 assert p.term() is not None 2921 pass 2922 #print 'Particle term: %s' % (object.__str__(p.term()),) 2923 #print 'Model group with %d particles produced %d element declarations' % (len(self.particles()), len(element_decls)) 2924 return element_decls
2925 2926 # aFS:MG
2927 - def _adaptForScope (self, owner, ctd):
2928 #print 'aFS:MG - %s' % (ctd.expandedName(),) 2929 rv = self 2930 assert isinstance(ctd, ComplexTypeDefinition) 2931 maybe_rv = self._clone(owner, ctd._objectOrigin()) 2932 scoped_particles = [ _p._adaptForScope(maybe_rv, ctd) for _p in self.particles() ] 2933 do_clone = (self._scope() != ctd) or (self.particles() != scoped_particles) 2934 if do_clone: 2935 rv = maybe_rv 2936 rv.__particles = scoped_particles 2937 return rv
2938
2939 - def __str__ (self):
2940 comp = None 2941 if self.C_ALL == self.compositor(): 2942 comp = 'ALL' 2943 elif self.C_CHOICE == self.compositor(): 2944 comp = 'CHOICE' 2945 elif self.C_SEQUENCE == self.compositor(): 2946 comp = 'SEQUENCE' 2947 return '%s:(%s)' % (comp, ",".join( [ str(_p) for _p in self.particles() ] ) )
2948
2949 -class Particle (_SchemaComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin):
2950 """An XMLSchema U{Particle<http://www.w3.org/TR/xmlschema-1/#cParticle>} component.""" 2951 2952 # The minimum number of times the term may appear. 2953 __minOccurs = 1
2954 - def minOccurs (self):
2955 """The minimum number of times the term may appear. 2956 2957 Defaults to 1.""" 2958 return self.__minOccurs
2959 2960 # Upper limit on number of times the term may appear. 2961 __maxOccurs = 1
2962 - def maxOccurs (self):
2963 """Upper limit on number of times the term may appear. 2964 2965 If None, the term may appear any number of times; otherwise, 2966 this is an integral value indicating the maximum number of times 2967 the term may appear. The default value is 1; the value, unless 2968 None, must always be at least minOccurs(). 2969 """ 2970 return self.__maxOccurs
2971 2972 # A reference to a ModelGroup, WildCard, or ElementDeclaration 2973 __term = None
2974 - def term (self):
2975 """A reference to a ModelGroup, Wildcard, or ElementDeclaration.""" 2976 return self.__term
2977 __pendingTerm = None 2978
2979 - def elementDeclarations (self):
2980 assert self.__term is not None 2981 if isinstance(self.__term, ModelGroup): 2982 return self.__term.elementDeclarations() 2983 if isinstance(self.__term, ElementDeclaration): 2984 return [ self.__term ] 2985 if isinstance(self.__term, Wildcard): 2986 return [ ] 2987 raise pyxb.LogicError('Unexpected term type %s' % (self.__term,))
2988
2989 - def pluralityData (self):
2990 """Return the plurality data for this component. 2991 2992 The plurality data for a particle is the plurality data for 2993 its term, with the counts scaled by the effect of 2994 maxOccurs.""" 2995 return _PluralityData(self)
2996
2997 - def effectiveTotalRange (self):
2998 """Extend the concept of effective total range to all particles. 2999 3000 See http://www.w3.org/TR/xmlschema-1/#cos-seq-range 3001 """ 3002 if isinstance(self.__term, ModelGroup): 3003 return self.__term.effectiveTotalRange(self) 3004 return (self.minOccurs(), self.maxOccurs())
3005
3006 - def isEmptiable (self):
3007 """Return C{True} iff this particle can legitimately match an empty 3008 sequence (no content). 3009 3010 See http://www.w3.org/TR/xmlschema-1/#cos-group-emptiable. 3011 """ 3012 return 0 == self.effectiveTotalRange()[0]
3013
3014 - def hasWildcardElement (self):
3015 """Return True iff this particle has a wildcard in its term. 3016 3017 Note that the wildcard may be in a nested model group.""" 3018 return self.term().hasWildcardElement()
3019
3020 - def __init__ (self, term, *args, **kw):
3021 """Create a particle from the given DOM node. 3022 3023 term is a XML Schema Component: one of ModelGroup, 3024 ElementDeclaration, and Wildcard. 3025 3026 The following keyword arguments are processed: 3027 3028 min_occurs is a non-negative integer value with default 1, 3029 denoting the minimum number of terms required by the content 3030 model. 3031 3032 max_occurs is a positive integer value with default 1, or None 3033 indicating unbounded, denoting the maximum number of terms 3034 allowed by the content model. 3035 3036 scope is the _ScopeDeclaration_mxin context that is assigned 3037 to declarations that appear within the particle. It can be 3038 None, indicating no scope defined, or a complex type 3039 definition. 3040 """ 3041 3042 super(Particle, self).__init__(*args, **kw) 3043 3044 min_occurs = kw.get('min_occurs', 1) 3045 max_occurs = kw.get('max_occurs', 1) 3046 3047 assert 'scope' in kw 3048 assert (self._scopeIsIndeterminate()) or isinstance(self._scope(), ComplexTypeDefinition) 3049 3050 if term is not None: 3051 self.__term = term 3052 3053 assert isinstance(min_occurs, (types.IntType, types.LongType)) 3054 self.__minOccurs = min_occurs 3055 assert (max_occurs is None) or isinstance(max_occurs, (types.IntType, types.LongType)) 3056 self.__maxOccurs = max_occurs 3057 if self.__maxOccurs is not None: 3058 if self.__minOccurs > self.__maxOccurs: 3059 raise pyxb.LogicError('Particle minOccurs %s is greater than maxOccurs %s on creation' % (min_occurs, max_occurs))
3060 3061 # res:Particle
3062 - def _resolve (self):
3063 if self.isResolved(): 3064 return self 3065 scope = self._scope() 3066 3067 # @RESOLUTION@ 3068 if ModelGroup == self.__resolvableType: 3069 ref_en = self._namespaceContext().interpretQName(self.__refAttribute) 3070 group_decl = ref_en.modelGroupDefinition() 3071 if group_decl is None: 3072 raise pyxb.SchemaValidationError('Model group reference %s cannot be found' % (ref_en,)) 3073 3074 self.__pendingTerm = group_decl.modelGroup() 3075 assert self.__pendingTerm is not None 3076 elif ElementDeclaration == self.__resolvableType: 3077 # 3.9.2 says use 3.3.2, which is Element. The element inside a 3078 # particle is a localElement, so we either get the one it refers 3079 # to (which is top-level), or create a local one here. 3080 if self.__refAttribute is not None: 3081 assert self.__pendingTerm is None 3082 ref_en = self._namespaceContext().interpretQName(self.__refAttribute) 3083 self.__pendingTerm = ref_en.elementDeclaration() 3084 if self.__pendingTerm is None: 3085 raise pyxb.SchemaValidationError('Unable to locate element referenced by %s' % (ref_en,)) 3086 assert self.__pendingTerm is not None 3087 3088 # Whether this is a local declaration or one pulled in from the 3089 # global type definition symbol space, its name is now reserved in 3090 # this type. 3091 assert self.__pendingTerm is not None 3092 else: 3093 assert False 3094 3095 self.__term = self.__pendingTerm 3096 assert self.__term is not None 3097 return self
3098
3099 - def isResolved (self):
3100 return self.__term is not None
3101 3102 # CFD:Particle 3103 @classmethod
3104 - def CreateFromDOM (cls, node, **kw):
3105 """Create a particle from the given DOM node. 3106 3107 wxs is a Schema instance within which the model group is being 3108 defined. 3109 3110 node is a DOM element. The name must be one of ( 'group', 3111 'element', 'any', 'all', 'choice', 'sequence' ), and the node 3112 must be in the XMLSchema namespace. 3113 3114 scope is the _ScopeDeclaration_mxin context that is assigned 3115 to declarations that appear within the model group. It can be 3116 None, indicating no scope defined, or a complex type 3117 definition. 3118 """ 3119 scope = kw['scope'] 3120 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or isinstance(scope, ComplexTypeDefinition) 3121 3122 kw.update({ 'min_occurs' : 1 3123 , 'max_occurs' : 1 3124 , 'node' : node }) 3125 3126 if not Particle.IsParticleNode(node): 3127 raise pyxb.LogicError('Attempted to create particle from illegal element %s' % (node.nodeName,)) 3128 attr_val = NodeAttribute(node, 'minOccurs') 3129 if attr_val is not None: 3130 kw['min_occurs'] = datatypes.nonNegativeInteger(attr_val) 3131 attr_val = NodeAttribute(node, 'maxOccurs') 3132 if attr_val is not None: 3133 if 'unbounded' == attr_val: 3134 kw['max_occurs'] = None 3135 else: 3136 kw['max_occurs'] = datatypes.nonNegativeInteger(attr_val) 3137 3138 rv = cls(None, **kw) 3139 3140 kw.pop('node', None) 3141 kw['owner'] = rv 3142 3143 rv.__refAttribute = NodeAttribute(node, 'ref') 3144 rv.__pendingTerm = None 3145 rv.__resolvableType = None 3146 if xsd.nodeIsNamed(node, 'group'): 3147 # 3.9.2 says use 3.8.2, which is ModelGroup. The group 3148 # inside a particle is a groupRef. If there is no group 3149 # with that name, this throws an exception as expected. 3150 if rv.__refAttribute is None: 3151 raise pyxb.SchemaValidationError('group particle without reference') 3152 rv.__resolvableType = ModelGroup 3153 elif xsd.nodeIsNamed(node, 'element'): 3154 if rv.__refAttribute is None: 3155 schema = kw.get('schema') 3156 assert schema is not None 3157 target_namespace = schema.targetNamespaceForNode(node, ElementDeclaration) 3158 incoming_tns = kw.get('target_namespace') 3159 if incoming_tns is not None: 3160 assert incoming_tns == target_namespace 3161 else: 3162 kw['target_namespace'] = target_namespace 3163 rv.__term = ElementDeclaration.CreateFromDOM(node=node, **kw) 3164 else: 3165 # NOTE: 3.3.3 clause 2.2 specifies that if ref is used, all 3166 # the other configuration attributes like nillable and default 3167 # must be absent. We don't even bother looking for them. 3168 rv.__resolvableType = ElementDeclaration 3169 assert not xsd.nodeIsNamed(node.parentNode, 'schema') 3170 elif xsd.nodeIsNamed(node, 'any'): 3171 # 3.9.2 says use 3.10.2, which is Wildcard. 3172 rv.__term = Wildcard.CreateFromDOM(node=node) 3173 elif ModelGroup.IsGroupMemberNode(node): 3174 # Choice, sequence, and all inside a particle are explicit 3175 # groups (or a restriction of explicit group, in the case 3176 # of all) 3177 rv.__term = ModelGroup.CreateFromDOM(node, **kw) 3178 else: 3179 raise pyxb.LogicError('Unhandled node in Particle.CreateFromDOM: %s' % (node.toxml(),)) 3180 3181 if not rv.isResolved(): 3182 rv._queueForResolution('creation') 3183 return rv
3184 3185 # bR:PRT
3186 - def _bindingRequires_vx (self, include_lax):
3187 if not include_lax: 3188 return frozenset() 3189 return frozenset([ self.__term ])
3190 3191 # aFS:PRT
3192 - def _adaptForScope (self, owner, ctd):
3193 #print 'aFS:PRT - %s' % (ctd.expandedName(),) 3194 rv = self 3195 assert isinstance(ctd, ComplexTypeDefinition) 3196 maybe_rv = self._clone(owner, ctd._objectOrigin()) 3197 term = rv.__term._adaptForScope(maybe_rv, ctd) 3198 do_clone = (self._scope() != ctd) or (rv.__term != term) 3199 if do_clone: 3200 rv = maybe_rv 3201 rv.__term = term 3202 return rv
3203
3204 - def isAdaptable (self, ctd):
3205 """A particle has an unresolvable particle if it cannot be 3206 resolved, or if it has resolved to a term which is a model 3207 group that has an unresolvable particle. 3208 """ 3209 if not self.isResolved(): 3210 return False 3211 return self.term().isAdaptable(ctd)
3212 3213 @classmethod
3214 - def IsTypedefNode (cls, node):
3215 return xsd.nodeIsNamed(node, 'group', 'all', 'choice', 'sequence')
3216 3217 @classmethod
3218 - def IsParticleNode (cls, node, *others):
3219 return xsd.nodeIsNamed(node, 'group', 'all', 'choice', 'sequence', 'element', 'any', *others)
3220
3221 - def __str__ (self):
3222 #return 'PART{%s:%d,%s}' % (self.term(), self.minOccurs(), self.maxOccurs()) 3223 return 'PART{%s:%d,%s}[%x]' % ('TERM', self.minOccurs(), self.maxOccurs(), id(self))
3224
3225 3226 # 3.10.1 3227 -class Wildcard (_SchemaComponent_mixin, _Annotated_mixin):
3228 """An XMLSchema U{Wildcard<http://www.w3.org/TR/xmlschema-1/#cParticle>} component.""" 3229 3230 NC_any = '##any' #<<< The namespace constraint "##any" 3231 NC_not = '##other' #<<< A flag indicating constraint "##other" 3232 NC_targetNamespace = '##targetNamespace' 3233 NC_local = '##local' 3234 3235 __namespaceConstraint = None
3236 - def namespaceConstraint (self):
3237 """A constraint on the namespace for the wildcard. 3238 3239 Valid values are: 3240 - L{Wildcard.NC_any} 3241 - A tuple ( L{Wildcard.NC_not}, a_namespace ) 3242 - set(of_namespaces) 3243 3244 Note that namespace are represented by 3245 L{Namespace<pyxb.namespace.Namespace>} instances, not the URIs that 3246 actually define a namespace. Absence of a namespace is represented by 3247 C{None}, both in the "not" pair and in the set. 3248 """ 3249 return self.__namespaceConstraint
3250 3251 @classmethod
3252 - def IntensionalUnion (cls, constraints):
3253 """http://www.w3.org/TR/xmlschema-1/#cos-aw-union""" 3254 assert 0 < len(constraints) 3255 o1 = constraints.pop(0); 3256 while 0 < len(constraints): 3257 o2 = constraints.pop(0); 3258 # 1 3259 if (o1 == o2): 3260 continue 3261 # 2 3262 if (cls.NC_any == o1) or (cls.NC_any == o2): 3263 o1 = cls.NC_any 3264 continue 3265 # 3 3266 if isinstance(o1, set) and isinstance(o2, set): 3267 o1 = o1.union(o2) 3268 continue 3269 # 4 3270 if (isinstance(o1, tuple) and isinstance(o2, tuple)) and (o1[1] != o2[1]): 3271 o1 = ( cls.NC_not, None ) 3272 continue 3273 # At this point, one must be a negated namespace and the 3274 # other a set. Identify them. 3275 c_tuple = None 3276 c_set = None 3277 if isinstance(o1, tuple): 3278 assert isinstance(o2, set) 3279 c_tuple = o1 3280 c_set = o2 3281 else: 3282 assert isinstance(o1, set) 3283 assert isinstance(o2, tuple) 3284 c_tuple = o2 3285 c_set = o1 3286 negated_ns = c_tuple[1] 3287 if negated_ns is not None: 3288 # 5.1 3289 if (negated_ns in c_set) and (None in c_set): 3290 o1 = cls.NC_any 3291 continue 3292 # 5.2 3293 if negated_ns in c_set: 3294 o1 = ( cls.NC_not, None ) 3295 continue 3296 # 5.3 3297 if None in c_set: 3298 raise pyxb.SchemaValidationError('Union of wildcard namespace constraints not expressible') 3299 o1 = c_tuple 3300 continue 3301 # 6 3302 if None in c_set: 3303 o1 = cls.NC_any 3304 else: 3305 o1 = ( cls.NC_not, None ) 3306 return o1
3307 3308 @classmethod
3309 - def IntensionalIntersection (cls, constraints):
3310 """http://www.w3.org/TR/xmlschema-1/#cos-aw-intersect""" 3311 assert 0 < len(constraints) 3312 o1 = constraints.pop(0); 3313 while 0 < len(constraints): 3314 o2 = constraints.pop(0); 3315 # 1 3316 if (o1 == o2): 3317 continue 3318 # 2 3319 if (cls.NC_any == o1) or (cls.NC_any == o2): 3320 if cls.NC_any == o1: 3321 o1 = o2 3322 continue 3323 # 4 3324 if isinstance(o1, set) and isinstance(o2, set): 3325 o1 = o1.intersection(o2) 3326 continue 3327 if isinstance(o1, tuple) and isinstance(o2, tuple): 3328 ns1 = o1[1] 3329 ns2 = o2[1] 3330 # 5 3331 if (ns1 is not None) and (ns2 is not None) and (ns1 != ns2): 3332 raise pyxb.SchemaValidationError('Intersection of wildcard namespace constraints not expressible') 3333 # 6 3334 assert (ns1 is None) or (ns2 is None) 3335 if ns1 is None: 3336 assert ns2 is not None 3337 o1 = ( cls.NC_not, ns2 ) 3338 else: 3339 assert ns1 is not None 3340 o1 = ( cls.NC_not, ns1 ) 3341 continue 3342 # 3 3343 # At this point, one must be a negated namespace and the 3344 # other a set. Identify them. 3345 c_tuple = None 3346 c_set = None 3347 if isinstance(o1, tuple): 3348 assert isinstance(o2, set) 3349 c_tuple = o1 3350 c_set = o2 3351 else: 3352 assert isinstance(o1, set) 3353 assert isinstance(o2, tuple) 3354 c_tuple = o2 3355 c_set = o1 3356 negated_ns = c_tuple[1] 3357 if negated_ns in c_set: 3358 c_set.remove(negated_ns) 3359 if None in c_set: 3360 c_set.remove(None) 3361 o1 = c_set 3362 return o1
3363 3364 PC_skip = 'skip' #<<< No constraint is applied 3365 PC_lax = 'lax' #<<< Validate against available uniquely determined declaration 3366 PC_strict = 'strict' #<<< Validate against declaration or xsi:type which must be available 3367 3368 # One of PC_* 3369 __processContents = None
3370 - def processContents (self): return self.__processContents
3371
3372 - def pluralityData (self):
3373 """Get the plurality data for this wildcard 3374 """ 3375 return _PluralityData(self)
3376
3377 - def hasWildcardElement (self):
3378 """Return True, since Wildcard components are wildcards.""" 3379 return True
3380
3381 - def __init__ (self, *args, **kw):
3382 assert 0 == len(args) 3383 super(Wildcard, self).__init__(*args, **kw) 3384 self.__namespaceConstraint = kw['namespace_constraint'] 3385 self.__processContents = kw['process_contents']
3386
3387 - def isAdaptable (self, ctd):
3388 return True
3389 3390 # aFS:WC
3391 - def _adaptForScope (self, owner, ctd):
3392 """Wildcards are scope-independent; return self""" 3393 return self
3394 3395 # CFD:Wildcard 3396 @classmethod
3397 - def CreateFromDOM (cls, node, **kw):
3398 namespace_context = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node) 3399 assert xsd.nodeIsNamed(node, 'any', 'anyAttribute') 3400 nc = NodeAttribute(node, 'namespace') 3401 if nc is None: 3402 namespace_constraint = cls.NC_any 3403 else: 3404 if cls.NC_any == nc: 3405 namespace_constraint = cls.NC_any 3406 elif cls.NC_not == nc: 3407 namespace_constraint = ( cls.NC_not, namespace_context.targetNamespace() ) 3408 else: 3409 ncs = set() 3410 for ns_uri in nc.split(): 3411 if cls.NC_local == ns_uri: 3412 ncs.add(None) 3413 elif cls.NC_targetNamespace == ns_uri: 3414 ncs.add(namespace_context.targetNamespace()) 3415 else: 3416 ncs.add(pyxb.namespace.NamespaceForURI(ns_uri, create_if_missing=True)) 3417 namespace_constraint = frozenset(ncs) 3418 3419 pc = NodeAttribute(node, 'processContents') 3420 if pc is None: 3421 process_contents = cls.PC_strict 3422 else: 3423 if pc in [ cls.PC_skip, cls.PC_lax, cls.PC_strict ]: 3424 process_contents = pc 3425 else: 3426 raise pyxb.SchemaValidationError('illegal value "%s" for any processContents attribute' % (pc,)) 3427 3428 rv = cls(node=node, namespace_constraint=namespace_constraint, process_contents=process_contents, **kw) 3429 rv._annotationFromDOM(node) 3430 return rv
3431
3432 # 3.11.1 3433 -class IdentityConstraintDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, _Annotated_mixin, pyxb.namespace.resolution._Resolvable_mixin):
3434 """An XMLSchema U{Identity Constraint Definition<http://www.w3.org/TR/xmlschema-1/#cIdentity-constraint_Definitions>} component.""" 3435 3436 ICC_KEY = 0x01 3437 ICC_KEYREF = 0x02 3438 ICC_UNIQUE = 0x04 3439 3440 __identityConstraintCategory = None 3442 3443 __selector = None
3444 - def selector (self): return self.__selector
3445 3446 __fields = None
3447 - def fields (self): return self.__fields
3448 3449 __referencedKey = None 3450 3451 __annotations = None
3452 - def annotations (self): return self.__annotations
3453 3454 # CFD:ICD CFD:IdentityConstraintDefinition 3455 @classmethod
3456 - def CreateFromDOM (cls, node, **kw):
3457 name = NodeAttribute(node, 'name') 3458 scope = kw['scope'] 3459 assert _ScopedDeclaration_mixin.ScopeIsIndeterminate(scope) or _ScopedDeclaration_mixin.IsValidScope(scope) 3460 rv = cls(name=name, node=node, **kw) 3461 3462 kw.pop('node', None) 3463 kw['owner'] = rv 3464 3465 #self._annotationFromDOM(node); 3466 rv.__isResolved = True 3467 icc = None 3468 if xsd.nodeIsNamed(node, 'key'): 3469 icc = rv.ICC_KEY 3470 elif xsd.nodeIsNamed(node, 'keyref'): 3471 icc = rv.ICC_KEYREF 3472 rv.__referAttribute = NodeAttribute(node, 'refer') 3473 if rv.__referAttribute is None: 3474 raise pyxb.SchemaValidationError('Require refer attribute on keyref elements') 3475 rv.__isResolved = False 3476 elif xsd.nodeIsNamed(node, 'unique'): 3477 icc = rv.ICC_UNIQUE 3478 else: 3479 raise pyxb.LogicError('Unexpected identity constraint node %s' % (node.toxml(),)) 3480 rv.__icc = icc 3481 3482 cn = LocateUniqueChild(node, 'selector') 3483 rv.__selector = NodeAttribute(cn, 'xpath') 3484 if rv.__selector is None: 3485 raise pyxb.SchemaValidationError('selector element missing xpath attribute') 3486 3487 rv.__fields = [] 3488 for cn in LocateMatchingChildren(node, 'field'): 3489 xp_attr = NodeAttribute(cn, 'xpath') 3490 if xp_attr is None: 3491 raise pyxb.SchemaValidationError('field element missing xpath attribute') 3492 rv.__fields.append(xp_attr) 3493 3494 rv._annotationFromDOM(node) 3495 rv.__annotations = [] 3496 if rv.annotation() is not None: 3497 rv.__annotations.append(rv) 3498 3499 for cn in node.childNodes: 3500 if (Node.ELEMENT_NODE != cn.nodeType): 3501 continue 3502 an = None 3503 if xsd.nodeIsNamed(cn, 'selector', 'field'): 3504 an = LocateUniqueChild(cn, 'annotation') 3505 elif xsd.nodeIsNamed(cn, 'annotation'): 3506 an = cn 3507 if an is not None: 3508 rv.__annotations.append(Annotation.CreateFromDOM(an, **kw)) 3509 3510 rv.__identityConstraintCategory = icc 3511 if rv.ICC_KEYREF != rv.__identityConstraintCategory: 3512 rv._namespaceContext().targetNamespace().addCategoryObject('identityConstraintDefinition', rv.name(), rv) 3513 3514 if not rv.isResolved(): 3515 rv._queueForResolution('creation') 3516 return rv
3517 3518 __isResolved = False
3519 - def isResolved (self):
3520 return self.__isResolved
3521 3522 # res:ICD res:IdentityConstraintDefinition
3523 - def _resolve (self):
3524 if self.isResolved(): 3525 return self 3526 3527 icc = self.__icc 3528 if self.ICC_KEYREF == icc: 3529 refer_en = self._namespaceContext().interpretQName(self.__referAttribute) 3530 refer = refer_en.identityConstraintDefinition() 3531 if refer is None: 3532 self._queueForResolution('Identity constraint definition %s cannot be found' % (refer_en,)) 3533 return self 3534 self.__referencedKey = refer 3535 self.__isResolved = True 3536 return self
3537 3538 # bR:ICD
3539 - def _bindingRequires_vx (self, include_lax):
3540 """Constraint definitions that are by reference require the referenced constraint.""" 3541 rv = set() 3542 if include_lax and (self.__referencedKey is not None): 3543 rv.add(self.__referencedKey) 3544 return frozenset(rv)
3545
3546 3547 3548 # 3.12.1 3549 -class NotationDeclaration (_SchemaComponent_mixin, _NamedComponent_mixin, _Annotated_mixin):
3550 """An XMLSchema U{Notation Declaration<http://www.w3.org/TR/xmlschema-1/#cNotation_Declarations>} component.""" 3551 __systemIdentifier = None
3552 - def systemIdentifier (self): return self.__systemIdentifier
3553 3554 __publicIdentifier = None
3555 - def publicIdentifier (self): return self.__publicIdentifier
3556 3557 # CFD:ND CFD:NotationDeclaration 3558 @classmethod
3559 - def CreateFromDOM (cls, node, **kw):
3560 name = NodeAttribute(node, 'name') 3561 rv = cls(name=name, node=node, **kw) 3562 3563 rv.__systemIdentifier = NodeAttribute(node, 'system') 3564 rv.__publicIdentifier = NodeAttribute(node, 'public') 3565 3566 rv._annotationFromDOM(node) 3567 return rv
3568
3569 # 3.13.1 3570 -class Annotation (_SchemaComponent_mixin):
3571 """An XMLSchema U{Annotation<http://www.w3.org/TR/xmlschema-1/#cAnnotation>} component.""" 3572 3573 __applicationInformation = None
3574 - def applicationInformation (self):
3575 return self.__applicationInformation
3576 3577 __userInformation = None
3578 - def userInformation (self):
3579 return self.__userInformation
3580 3581 # Define so superclasses can take keywords
3582 - def __init__ (self, **kw):
3583 application_information = kw.pop('application_information', None) 3584 user_information = kw.pop('user_information', None) 3585 super(Annotation, self).__init__(**kw) 3586 if (user_information is not None) and (not isinstance(user_information, list)): 3587 user_information = [ unicode(user_information) ] 3588 if (application_information is not None) and (not isinstance(application_information, list)): 3589 application_information = [ unicode(application_information) ] 3590 self.__userInformation = user_information 3591 self.__applicationInformation = application_information
3592 3593 # @todo: what the hell is this? From 3.13.2, I think it's a place 3594 # to stuff attributes from the annotation element, which makes 3595 # sense, as well as from the annotation's parent element, which 3596 # doesn't. Apparently it's for attributes that don't belong to 3597 # the XMLSchema namespace; so maybe we're not supposed to add 3598 # those to the other components. Note that these are attribute 3599 # information items, not attribute uses. 3600 __attributes = None 3601 3602 # CFD:Annotation 3603 @classmethod
3604 - def CreateFromDOM (cls, node, **kw):
3605 rv = cls(node=node, **kw) 3606 3607 # @todo:: Scan for attributes in the node itself that do not 3608 # belong to the XMLSchema namespace. 3609 3610 # Node should be an XMLSchema annotation node 3611 assert xsd.nodeIsNamed(node, 'annotation') 3612 app_info = [] 3613 user_info = [] 3614 for cn in node.childNodes: 3615 if xsd.nodeIsNamed(cn, 'appinfo'): 3616 app_info.append(cn) 3617 elif xsd.nodeIsNamed(cn, 'documentation'): 3618 user_info.append(cn) 3619 else: 3620 pass 3621 if 0 < len(app_info): 3622 rv.__applicationInformation = app_info 3623 if 0 < len(user_info): 3624 rv.__userInformation = user_info 3625 3626 return rv
3627 3628 __RemoveMultiQuote_re = re.compile('""+')
3629 - def asDocString (self, encoding='ascii', error='xmlcharrefreplace'):
3630 """Return the text in a form suitable for embedding in a 3631 triple-double-quoted docstring. 3632 3633 Any sequence of two or more double quotes is replaced by a sequence of 3634 single quotes that is the same length. Following this, spaces are 3635 added at the start and the end as necessary to ensure a double quote 3636 does not appear in those positions.""" 3637 rv = self.text().encode(encoding, error) 3638 rv = self.__RemoveMultiQuote_re.sub(lambda _mo: "'" * (_mo.end(0) - _mo.start(0)), rv) 3639 if rv.startswith('"'): 3640 rv = ' ' + rv 3641 if rv.endswith('"'): 3642 rv = rv + ' ' 3643 return rv
3644
3645 - def text (self):
3646 if self.__userInformation is None: 3647 return '' 3648 text = [] 3649 # Values in userInformation are DOM "documentation" elements. 3650 # We want their combined content. 3651 for dn in self.__userInformation: 3652 for cn in dn.childNodes: 3653 if Node.TEXT_NODE == cn.nodeType: 3654 text.append(cn.data) 3655 return ''.join(text)
3656
3657 - def __str__ (self):
3658 """Return the catenation of all user information elements in the 3659 annotation as a single unicode string. Returns the empty string if 3660 there are no user information elements.""" 3661 return self.text() 3662 text = [] 3663 if not self.__userInformation: 3664 return ''
3665
3666 # Section 3.14. 3667 -class SimpleTypeDefinition (_SchemaComponent_mixin, _NamedComponent_mixin, pyxb.namespace.resolution._Resolvable_mixin, _Annotated_mixin):
3668 """An XMLSchema U{Simple Type Definition<http://www.w3.org/TR/xmlschema-1/#Simple_Type_Definitions>} component.""" 3669 3670 # Reference to the SimpleTypeDefinition on which this is based. 3671 # The value must be non-None except for the simple ur-type 3672 # definition. 3673 __baseTypeDefinition = None
3674 - def baseTypeDefinition (self):
3675 return self.__baseTypeDefinition
3676 3677 # A map from a subclass of facets.Facet to an instance of that class. 3678 # Presence of a facet class as a key in this map is the indicator that the 3679 # type definition and its subtypes are permitted to use the corresponding 3680 # facet. All facets in force for this type are present in the map, 3681 # including those constraints inherited parent types. 3682 __facets = None
3683 - def facets (self):
3684 assert (self.__facets is None) or (type(self.__facets) == types.DictType) 3685 return self.__facets
3686 3687 # The facets.FundamentalFacet instances that describe this type 3688 __fundamentalFacets = None
3689 - def fundamentalFacets (self):
3690 """A frozenset of instances of facets.FundamentallFacet.""" 3691 return self.__fundamentalFacets
3692 3693 STD_empty = 0 #<<< Marker indicating an empty set of STD forms 3694 STD_extension = 0x01 #<<< Representation for extension in a set of STD forms 3695 STD_list = 0x02 #<<< Representation for list in a set of STD forms 3696 STD_restriction = 0x04 #<<< Representation of restriction in a set of STD forms 3697 STD_union = 0x08 #<<< Representation of union in a set of STD forms 3698 3699 _STD_Map = { 'extension' : STD_extension 3700 , 'list' : STD_list 3701 , 'restriction' : STD_restriction 3702 , 'union' : STD_union } 3703 3704 # Bitmask defining the subset that comprises the final property 3705 __final = STD_empty 3706 @classmethod
3707 - def _FinalToString (cls, final_value):
3708 """Convert a final value to a string.""" 3709 tags = [] 3710 if final_value & cls.STD_extension: 3711 tags.append('extension') 3712 if final_value & cls.STD_list: 3713 tags.append('list') 3714 if final_value & cls.STD_restriction: 3715 tags.append('restriction') 3716 if final_value & cls.STD_union: 3717 tags.append('union') 3718 return ' '.join(tags)
3719 3720 VARIETY_absent = 0x01 #<<< Only used for the ur-type 3721 VARIETY_atomic = 0x02 #<<< Use for types based on a primitive type 3722 VARIETY_list = 0x03 #<<< Use for lists of atomic-variety types 3723 VARIETY_union = 0x04 #<<< Use for types that aggregate other types 3724 3725 # Derivation alternative 3726 _DA_empty = 'none specified' 3727 _DA_restriction = 'restriction' 3728 _DA_list = 'list' 3729 _DA_union = 'union' 3730
3731 - def _derivationAlternative (self):
3732 return self.__derivationAlternative
3733 __derivationAlternative = None 3734 3735 # Identify the sort of value collection this holds. This field is 3736 # used to identify unresolved definitions. 3737 __variety = None
3738 - def variety (self):
3739 return self.__variety
3740 @classmethod
3741 - def VarietyToString (cls, variety):
3742 """Convert a variety value to a string.""" 3743 if cls.VARIETY_absent == variety: 3744 return 'absent' 3745 if cls.VARIETY_atomic == variety: 3746 return 'atomic' 3747 if cls.VARIETY_list == variety: 3748 return 'list' 3749 if cls.VARIETY_union == variety: 3750 return 'union' 3751 return '?NoVariety?'
3752 3753 # For atomic variety only, the root (excepting ur-type) type. 3754 __primitiveTypeDefinition = None
3755 - def primitiveTypeDefinition (self, throw_if_absent=True):
3756 if throw_if_absent: 3757 if self.variety() != self.VARIETY_atomic: 3758 raise pyxb.BadPropertyError('[%s] primitiveTypeDefinition only defined for atomic types' % (self.name(), self.variety())) 3759 if self.__primitiveTypeDefinition is None: 3760 raise pyxb.LogicError('Expected primitive type for %s in %s', self, self.targetNamespace()) 3761 return self.__primitiveTypeDefinition
3762 3763 # For list variety only, the type of items in the list 3764 __itemTypeDefinition = None
3765 - def itemTypeDefinition (self):
3766 if self.VARIETY_list != self.variety(): 3767 raise pyxb.BadPropertyError('itemTypeDefinition only defined for list types') 3768 if self.__itemTypeDefinition is None: 3769 raise pyxb.LogicError('Expected item type') 3770 return self.__itemTypeDefinition
3771 3772 # For union variety only, the sequence of candidate members 3773 __memberTypeDefinitions = None
3774 - def memberTypeDefinitions (self):
3775 if self.VARIETY_union != self.variety(): 3776 raise pyxb.BadPropertyError('memberTypeDefinitions only defined for union types') 3777 if self.__memberTypeDefinitions is None: 3778 raise pyxb.LogicError('Expected member types') 3779 return self.__memberTypeDefinitions
3780 3781 # bR:STD
3782 - def _bindingRequires_vx (self, include_lax):
3783 """Implement base class method. 3784 3785 This STD depends on its baseTypeDefinition, unless its variety 3786 is absent. Other dependencies are on item, primitive, or 3787 member type definitions.""" 3788 type_definitions = set() 3789 if self != self.baseTypeDefinition(): 3790 type_definitions.add(self.baseTypeDefinition()) 3791 if self.VARIETY_absent == self.variety(): 3792 type_definitions = set() 3793 elif self.VARIETY_atomic == self.variety(): 3794 if self != self.primitiveTypeDefinition(): 3795 type_definitions.add(self.primitiveTypeDefinition()) 3796 elif self.VARIETY_list == self.variety(): 3797 assert self != self.itemTypeDefinition() 3798 type_definitions.add(self.itemTypeDefinition()) 3799 elif self.VARIETY_union == self.variety(): 3800 assert self not in self.memberTypeDefinitions() 3801 type_definitions.update(self.memberTypeDefinitions()) 3802 else: 3803 raise pyxb.LogicError('Unable to identify dependent types: variety %s' % (self.variety(),)) 3804 # NB: This type also depends on the value type definitions for 3805 # any facets that apply to it. This fact only matters when 3806 # generating the datatypes_facets source. That, and the fact 3807 # that there are dependency loops (e.g., integer requires a 3808 # nonNegativeInteger for its length facet) means we don't 3809 # bother adding in those. 3810 return frozenset(type_definitions)
3811 3812 # A non-property field that holds a reference to the DOM node from 3813 # which the type is defined. The value is held only between the 3814 # point where the simple type definition instance is created until 3815 # the point it is resolved. 3816 __domNode = None 3817 3818 # Indicate that this instance was defined as a built-in rather 3819 # than from a DOM instance. 3820 __isBuiltin = False 3821 3822 # Allocate one of these. Users should use one of the Create* 3823 # factory methods instead. 3824
3825 - def __init__ (self, *args, **kw):
3826 super(SimpleTypeDefinition, self).__init__(*args, **kw) 3827 self.__variety = kw['variety']
3828
3829 - def __setstate__ (self, state):
3830 """Extend base class unpickle support to retain link between 3831 this instance and the Python class that it describes. 3832 3833 This is because the pythonSupport value is a class reference, 3834 not an instance reference, so it wasn't deserialized, and its 3835 class member link was never set. 3836 """ 3837 super_fn = getattr(super(SimpleTypeDefinition, self), '__setstate__', lambda _state: self.__dict__.update(_state)) 3838 super_fn(state) 3839 if self.__pythonSupport is not None: 3840 self.__pythonSupport._SimpleTypeDefinition(self)
3841
3842 - def __str__ (self):
3843 if self.name() is not None: 3844 elts = [ self.name(), ':' ] 3845 else: 3846 elts = [ '<anonymous>:' ] 3847 if self.VARIETY_absent == self.variety(): 3848 elts.append('the ur-type') 3849 elif self.VARIETY_atomic == self.variety(): 3850 elts.append('restriction of %s' % (self.baseTypeDefinition().name(),)) 3851 elif self.VARIETY_list == self.variety(): 3852 elts.append('list of %s' % (self.itemTypeDefinition().name(),)) 3853 elif self.VARIETY_union == self.variety(): 3854 elts.append('union of %s' % (" ".join([str(_mtd.name()) for _mtd in self.memberTypeDefinitions()],))) 3855 else: 3856 # Gets here if the type has not been resolved. 3857 elts.append('?') 3858 #raise pyxb.LogicError('Unexpected variety %s' % (self.variety(),)) 3859 if self.__facets: 3860 felts = [] 3861 for (k, v) in self.__facets.items(): 3862 if v is not None: 3863 felts.append(str(v)) 3864 elts.append("\n %s" % (','.join(felts),)) 3865 if self.__fundamentalFacets: 3866 elts.append("\n ") 3867 elts.append(','.join( [str(_f) for _f in self.__fundamentalFacets ])) 3868 return 'STD[%s]' % (''.join(elts),)
3869
3870 - def _updateFromOther_csc (self, other):
3871 """Override fields in this instance with those from the other. 3872 3873 This method is invoked only by Schema._addNamedComponent, and 3874 then only when a built-in type collides with a schema-defined 3875 type. Material like facets is not (currently) held in the 3876 built-in copy, so the DOM information is copied over to the 3877 built-in STD, which is subsequently re-resolved. 3878 3879 Returns self. 3880 """ 3881 assert self != other 3882 assert self.isNameEquivalent(other) 3883 super(SimpleTypeDefinition, self)._updateFromOther_csc(other) 3884 3885 # The other STD should be an unresolved schema-defined type. 3886 assert other.__baseTypeDefinition is None, 'Update from resolved STD %s' % (other,) 3887 assert other.__domNode is not None 3888 self.__domNode = other.__domNode 3889 3890 # Preserve the python support 3891 if other.__pythonSupport is not None: 3892 # @todo: ERROR multiple references 3893 self.__pythonSupport = other.__pythonSupport 3894 3895 # Mark this instance as unresolved so it is re-examined 3896 self.__variety = None 3897 return self
3898
3899 - def isBuiltin (self):
3900 """Indicate whether this simple type is a built-in type.""" 3901 return self.__isBuiltin
3902 3903 __SimpleUrTypeDefinition = None 3904 @classmethod
3905 - def SimpleUrTypeDefinition (cls, schema=None, in_builtin_definition=False):
3906 """Create the SimpleTypeDefinition instance that approximates the simple ur-type. 3907 3908 See section 3.14.7.""" 3909 3910 #if in_builtin_definition and (cls.__SimpleUrTypeDefinition is not None): 3911 # raise pyxb.LogicError('Multiple definitions of SimpleUrType') 3912 if cls.__SimpleUrTypeDefinition is None: 3913 # Note: We use a singleton subclass 3914 assert schema is not None 3915 3916 ns_ctx = schema.targetNamespace().initialNamespaceContext() 3917 3918 kw = { 'name' : 'anySimpleType', 3919 'schema' : schema, 3920 'namespace_context' : ns_ctx, 3921 'binding_namespace' : schema.targetNamespace(), 3922 'variety' : cls.VARIETY_absent, 3923 'scope' : _ScopedDeclaration_mixin.SCOPE_global } 3924 bi = _SimpleUrTypeDefinition(**kw) 3925 bi._setPythonSupport(datatypes.anySimpleType) 3926 3927 # The baseTypeDefinition is the ur-type. 3928 bi.__baseTypeDefinition = ComplexTypeDefinition.UrTypeDefinition() 3929 # The simple ur-type has an absent variety, not an atomic 3930 # variety, so does not have a primitiveTypeDefinition 3931 3932 # No facets on the ur type 3933 bi.__facets = {} 3934 bi.__fundamentalFacets = frozenset() 3935 3936 bi.__resolveBuiltin() 3937 3938 cls.__SimpleUrTypeDefinition = bi 3939 return cls.__SimpleUrTypeDefinition
3940 3941 @classmethod
3942 - def _CreateXMLInstance (cls, name, schema):
3943 """Create STD instances for built-in types. 3944 3945 For example, xml:space is a restriction of NCName; xml:lang is a union. 3946 3947 """ 3948 import pyxb.binding.xml_ 3949 kw = { 'schema' : schema, 3950 'binding_namespace' : schema.targetNamespace(), 3951 'namespace_context' : schema.targetNamespace().initialNamespaceContext(), 3952 'scope' : _ScopedDeclaration_mixin.SCOPE_global, 3953 'variety' : cls.VARIETY_atomic } 3954 ns_ctx = pyxb.namespace.XML.initialNamespaceContext() 3955 if 'space' == name: 3956 bi = cls(**kw) 3957 bi.__derivationAlternative = cls._DA_restriction 3958 bi.__baseTypeDefinition = datatypes.NCName.SimpleTypeDefinition() 3959 bi.__primitiveTypeDefinition = bi.__baseTypeDefinition.__primitiveTypeDefinition 3960 bi._setPythonSupport(pyxb.binding.xml_.STD_ANON_space) 3961 bi.setNameInBinding('STD_ANON_space') 3962 elif 'lang' == name: 3963 bi = cls(**kw) 3964 bi.__baseTypeDefinition = cls.SimpleUrTypeDefinition() 3965 bi.__memberTypes = [ datatypes.language.SimpleTypeDefinition() ] 3966 bi.__derivationAlternative = cls._DA_union 3967 bi.__primitiveTypeDefinition = bi 3968 bi._setPythonSupport(pyxb.binding.xml_.STD_ANON_lang) 3969 bi.setNameInBinding('STD_ANON_lang') 3970 else: 3971 raise pyxb.IncompleteImplementationError('No implementation for %s' % (name,)) 3972 bi.__facets = { } 3973 for v in bi.pythonSupport().__dict__.values(): 3974 if isinstance(v, facets.ConstrainingFacet): 3975 bi.__facets[v.__class__] = v 3976 return bi
3977 3978 @classmethod
3979 - def CreatePrimitiveInstance (cls, name, schema, python_support):
3980 """Create a primitive simple type in the target namespace. 3981 3982 This is mainly used to pre-load standard built-in primitive 3983 types, such as those defined by XMLSchema Datatypes. You can 3984 use it for your own schemas as well, if you have special types 3985 that require explicit support to for Pythonic conversion. 3986 3987 All parameters are required and must be non-None. 3988 """ 3989 3990 kw = { 'name' : name, 3991 'schema' : schema, 3992 'binding_namespace' : schema.targetNamespace(), 3993 'namespace_context' : schema.targetNamespace().initialNamespaceContext(), 3994 'scope' : _ScopedDeclaration_mixin.SCOPE_global, 3995 'variety' : cls.VARIETY_atomic } 3996 3997 bi = cls(**kw) 3998 bi._setPythonSupport(python_support) 3999 4000 # Primitive types are based on the ur-type, and have 4001 # themselves as their primitive type definition. 4002 bi.__baseTypeDefinition = cls.SimpleUrTypeDefinition() 4003 bi.__primitiveTypeDefinition = bi 4004 4005 # Primitive types are built-in 4006 bi.__resolveBuiltin() 4007 assert bi.isResolved() 4008 return bi
4009 4010 @classmethod
4011 - def CreateDerivedInstance (cls, name, schema, parent_std, python_support):
4012 """Create a derived simple type in the target namespace. 4013 4014 This is used to pre-load standard built-in derived types. You 4015 can use it for your own schemas as well, if you have special 4016 types that require explicit support to for Pythonic 4017 conversion. 4018 """ 4019 assert parent_std 4020 assert parent_std.__variety in (cls.VARIETY_absent, cls.VARIETY_atomic) 4021 kw = { 'name' : name, 4022 'schema' : schema, 4023 'binding_namespace' : schema.targetNamespace(), 4024 'namespace_context' : schema.targetNamespace().initialNamespaceContext(), 4025 'scope' : _ScopedDeclaration_mixin.SCOPE_global, 4026 'variety' : parent_std.__variety } 4027 4028 bi = cls(**kw) 4029 bi._setPythonSupport(python_support) 4030 4031 # We were told the base type. If this is atomic, we re-use 4032 # its primitive type. Note that these all may be in different 4033 # namespaces. 4034 bi.__baseTypeDefinition = parent_std 4035 if cls.VARIETY_atomic == bi.__variety: 4036 bi.__primitiveTypeDefinition = bi.__baseTypeDefinition.__primitiveTypeDefinition 4037 4038 # Derived types are built-in 4039 bi.__resolveBuiltin() 4040 return bi
4041 4042 @classmethod
4043 - def CreateListInstance (cls, name, schema, item_std, python_support):
4044 """Create a list simple type in the target namespace. 4045 4046 This is used to preload standard built-in list types. You can 4047 use it for your own schemas as well, if you have special types 4048 that require explicit support to for Pythonic conversion; but 4049 note that such support is identified by the item_std. 4050 """ 4051 4052 kw = { 'name' : name, 4053 'schema' : schema, 4054 'binding_namespace' : schema.targetNamespace(), 4055 'namespace_context' : schema.targetNamespace().initialNamespaceContext(), 4056 'scope' : _ScopedDeclaration_mixin.SCOPE_global, 4057 'variety' : cls.VARIETY_list } 4058 bi = cls(**kw) 4059 bi._setPythonSupport(python_support) 4060 4061 # The base type is the ur-type. We were given the item type. 4062 bi.__baseTypeDefinition = cls.SimpleUrTypeDefinition() 4063 assert item_std 4064 bi.__itemTypeDefinition = item_std 4065 4066 # List types are built-in 4067 bi.__resolveBuiltin() 4068 return bi
4069 4070 @classmethod
4071 - def CreateUnionInstance (cls, name, schema, member_stds):
4072 """(Placeholder) Create a union simple type in the target namespace. 4073 4074 This function has not been implemented.""" 4075 raise pyxb.IncompleteImplementationError('No support for built-in union types')
4076
4077 - def __singleSimpleTypeChild (self, body, other_elts_ok=False):
4078 simple_type_child = None 4079 for cn in body.childNodes: 4080 if (Node.ELEMENT_NODE == cn.nodeType): 4081 if not xsd.nodeIsNamed(cn, 'simpleType'): 4082 if other_elts_ok: 4083 continue 4084 raise pyxb.SchemaValidationError('Context requires element to be xs:simpleType') 4085 assert not simple_type_child 4086 simple_type_child = cn 4087 if simple_type_child is None: 4088 raise pyxb.SchemaValidationError('Content requires an xs:simpleType member (or a base attribute)') 4089 return simple_type_child
4090 4091 # The __initializeFrom* methods are responsible for identifying 4092 # the variety and the baseTypeDefinition. The remainder of the 4093 # resolution is performed by the __completeResolution method. 4094 # Note that in some cases resolution might yet be premature, so 4095 # variety is not saved until it is complete. All this stuff is 4096 # from section 3.14.2. 4097
4098 - def __initializeFromList (self, body, **kw):
4099 self.__baseTypeDefinition = self.SimpleUrTypeDefinition() 4100 self.__itemTypeAttribute = NodeAttribute(body, 'itemType') 4101 if self.__itemTypeAttribute is None: 4102 # NOTE: The newly created anonymous item type will 4103 # not be resolved; the caller needs to handle 4104 # that. 4105 self.__itemTypeDefinition = self.CreateFromDOM(self.__singleSimpleTypeChild(body), **kw) 4106 return self.__completeResolution(body, self.VARIETY_list, self._DA_list)
4107
4108 - def __initializeFromRestriction (self, body, **kw):
4109 if self.__baseTypeDefinition is None: 4110 self.__baseAttribute = NodeAttribute(body, 'base') 4111 if self.__baseAttribute is None: 4112 self.__baseTypeDefinition = self.CreateFromDOM(self.__singleSimpleTypeChild(body, other_elts_ok=True), **kw) 4113 return self.__completeResolution(body, None, self._DA_restriction)
4114 4115 __localMemberTypes = None
4116 - def __initializeFromUnion (self, body, **kw):
4117 self.__baseTypeDefinition = self.SimpleUrTypeDefinition() 4118 self.__memberTypesAttribute = NodeAttribute(body, 'memberTypes') 4119 if self.__localMemberTypes is None: 4120 self.__localMemberTypes = [] 4121 for cn in body.childNodes: 4122 if (Node.ELEMENT_NODE == cn.nodeType) and xsd.nodeIsNamed(cn, 'simpleType'): 4123 self.__localMemberTypes.append(self.CreateFromDOM(cn, **kw)) 4124 return self.__completeResolution(body, self.VARIETY_union, self._DA_union)
4125
4126 - def __resolveBuiltin (self):
4127 if self.hasPythonSupport(): 4128 self.__facets = { } 4129 for v in self.pythonSupport().__dict__.values(): 4130 if isinstance(v, facets.ConstrainingFacet): 4131 #print 'Adding facet %s to %s' % (v, self.name()) 4132 self.__facets[v.__class__] = v 4133 if v.ownerTypeDefinition() is None: 4134 v.setFromKeywords(_constructor=True, owner_type_definition=self) 4135 self.__isBuiltin = True 4136 return self
4137
4138 - def __defineDefaultFacets (self, variety):
4139 """Create facets for varieties that can take facets that are undeclared. 4140 4141 This means unions, which per section 4.1.2.3 of 4142 http://www.w3.org/TR/xmlschema-2/ can have enumeration or 4143 pattern restrictions.""" 4144 if self.VARIETY_union != variety: 4145 return self 4146 self.__facets.setdefault(facets.CF_pattern) 4147 self.__facets.setdefault(facets.CF_enumeration) 4148 return self
4149
4150 - def __processHasFacetAndProperty (self, variety):
4151 """Identify the facets and properties for this stype. 4152 4153 This method simply identifies the facets that apply to this 4154 specific type, and records property values. Only 4155 explicitly-associated facets and properties are stored; others 4156 from base types will also affect this type. The information 4157 is taken from the applicationInformation children of the 4158 definition's annotation node, if any. If there is no support 4159 for the XMLSchema_hasFacetAndProperty namespace, this is a 4160 no-op. 4161 4162 Upon return, self.__facets is a map from the class for an 4163 associated fact to None, and self.__fundamentalFacets is a 4164 frozenset of instances of FundamentalFacet. 4165 4166 The return value is self. 4167 """ 4168 self.__facets = { } 4169 self.__fundamentalFacets = frozenset() 4170 if self.annotation() is None: 4171 return self.__defineDefaultFacets(variety) 4172 app_info = self.annotation().applicationInformation() 4173 if app_info is None: 4174 return self.__defineDefaultFacets(variety) 4175 facet_map = { } 4176 fundamental_facets = set() 4177 seen_facets = set() 4178 for ai in app_info: 4179 for cn in ai.childNodes: 4180 if Node.ELEMENT_NODE != cn.nodeType: 4181 continue 4182 if pyxb.namespace.XMLSchema_hfp.nodeIsNamed(cn, 'hasFacet'): 4183 facet_name = NodeAttribute(cn, 'name')# , pyxb.namespace.XMLSchema_hfp) 4184 if facet_name is None: 4185 raise pyxb.SchemaValidationError('hasFacet missing name attribute in %s' % (cn,)) 4186 if facet_name in seen_facets: 4187 raise pyxb.SchemaValidationError('Multiple hasFacet specifications for %s' % (facet_name,)) 4188 seen_facets.add(facet_name) 4189 facet_class = facets.ConstrainingFacet.ClassForFacet(facet_name) 4190 #facet_map[facet_class] = facet_class(base_type_definition=self) 4191 facet_map[facet_class] = None 4192 if pyxb.namespace.XMLSchema_hfp.nodeIsNamed(cn, 'hasProperty'): 4193 fundamental_facets.add(facets.FundamentalFacet.CreateFromDOM(cn, self)) 4194 if 0 < len(facet_map): 4195 assert self.__baseTypeDefinition == self.SimpleUrTypeDefinition() 4196 self.__facets = facet_map 4197 assert type(self.__facets) == types.DictType 4198 if 0 < len(fundamental_facets): 4199 self.__fundamentalFacets = frozenset(fundamental_facets) 4200 return self
4201 4202 # NB: Must be done after resolution of the base type
4203 - def __updateFacets (self, body):
4204 4205 # Create local list consisting of facet classes matched in children 4206 # and the map of keywords used to initialize the local instance. 4207 4208 local_facets = {} 4209 for fc in facets.Facet.Facets: 4210 children = LocateMatchingChildren(body, fc.Name()) 4211 if 0 < len(children): 4212 fi = fc(base_type_definition=self.__baseTypeDefinition, 4213 owner_type_definition=self) 4214 if isinstance(fi, facets._LateDatatype_mixin): 4215 fi.bindValueDatatype(self) 4216 for cn in children: 4217 kw = { 'annotation': LocateUniqueChild(cn, 'annotation') } 4218 for ai in range(0, cn.attributes.length): 4219 attr = cn.attributes.item(ai) 4220 # Convert name from unicode to string 4221 kw[str(attr.localName)] = attr.value 4222 try: 4223 fi.setFromKeywords(**kw) 4224 except pyxb.PyXBException, e: 4225 raise pyxb.SchemaValidationError('Error assigning facet %s in %s: %s' % (fc.Name(), self.expandedName(), e)) 4226 local_facets[fc] = fi 4227 self.__localFacets = local_facets 4228 4229 # We want a map from the union of the facet classes from this STD up 4230 # through its baseTypeDefinition (if present). Map elements should be 4231 # to None if the facet has not been constrained, or to the nearest 4232 # ConstrainingFacet instance if it is. ConstrainingFacet instances 4233 # created for local constraints also need a pointer to the 4234 # corresponding facet from the ancestor type definition, because those 4235 # constraints also affect this type. 4236 base_facets = {} 4237 4238 # Built-ins didn't get their facets() setting configured, so use the 4239 # _FacetMap() instead. 4240 if self.__baseTypeDefinition.isBuiltin(): 4241 pstd = self.__baseTypeDefinition.pythonSupport() 4242 if pstd != datatypes.anySimpleType: 4243 base_facets.update(pstd._FacetMap()) 4244 elif self.__baseTypeDefinition.facets(): 4245 assert type(self.__baseTypeDefinition.facets()) == types.DictType 4246 base_facets.update(self.__baseTypeDefinition.facets()) 4247 base_facets.update(self.facets()) 4248 4249 self.__facets = self.__localFacets 4250 for fc in base_facets.keys(): 4251 self.__facets.setdefault(fc, base_facets[fc]) 4252 assert type(self.__facets) == types.DictType
4253
4254 - def _createRestriction (self, owner, body):
4255 """Create a new simple type with this as its base. 4256 4257 The type is owned by the provided owner, and may have facet 4258 restrictions defined by the body. 4259 @param owner: the owner for the newly created type 4260 @type owner: L{ComplexTypeDefinition} 4261 @param body: the DOM node from which facet information will be extracted 4262 @type body: C{xml.dom.Node} 4263 @rtype: L{SimpleTypeDefinition} 4264 """ 4265 std = SimpleTypeDefinition(owner=owner, namespace_context=owner._namespaceContext(), variety=None, scope=self._scope(), schema=owner._schema()) 4266 std.__baseTypeDefinition = self 4267 return std.__completeResolution(body, None, self._DA_restriction)
4268 4269 # Complete the resolution of some variety of STD. Note that the 4270 # variety is compounded by an alternative, since there is no 4271 # 'restriction' variety.
4272 - def __completeResolution (self, body, variety, alternative):
4273 assert self.__variety is None 4274 if self.__baseTypeDefinition is None: 4275 assert self.__baseAttribute is not None 4276 base_en = self._namespaceContext().interpretQName(self.__baseAttribute) 4277 base_type = base_en.typeDefinition() 4278 if not isinstance(base_type, SimpleTypeDefinition): 4279 raise pyxb.SchemaValidationError('Unable to locate base type %s' % (base_en,)) 4280 self.__baseTypeDefinition = base_type 4281 # If the base type exists but has not yet been resolved, 4282 # delay processing this type until the one it depends on 4283 # has been completed. 4284 assert self.__baseTypeDefinition != self 4285 if not self.__baseTypeDefinition.isResolved(): 4286 self._queueForResolution('base type %s is not resolved' % (self.__baseTypeDefinition,)) 4287 return self 4288 if variety is None: 4289 # 3.14.1 specifies that the variety is the variety of the base 4290 # type definition which, by the way, can't be the ur type. 4291 variety = self.__baseTypeDefinition.__variety 4292 assert variety is not None 4293 4294 if self.VARIETY_absent == variety: 4295 # The ur-type is always resolved. So are restrictions of it, 4296 # which is how we might get here. 4297 pass 4298 elif self.VARIETY_atomic == variety: 4299 # Atomic types (and their restrictions) use the primitive 4300 # type, which is the highest type that is below the 4301 # ur-type (which is not atomic). 4302 ptd = self 4303 while isinstance(ptd, SimpleTypeDefinition) and (self.VARIETY_atomic == ptd.__baseTypeDefinition.variety()): 4304 ptd = ptd.__baseTypeDefinition 4305 4306 self.__primitiveTypeDefinition = ptd 4307 elif self.VARIETY_list == variety: 4308 if self._DA_list == alternative: 4309 if self.__itemTypeAttribute is not None: 4310 it_en = self._namespaceContext().interpretQName(self.__itemTypeAttribute) 4311 self.__itemTypeDefinition = it_en.typeDefinition() 4312 if not isinstance(self.__itemTypeDefinition, SimpleTypeDefinition): 4313 raise pyxb.SchemaValidationError('Unable to locate STD %s for items' % (it_en,)) 4314 elif self._DA_restriction == alternative: 4315 self.__itemTypeDefinition = self.__baseTypeDefinition.__itemTypeDefinition 4316 else: 4317 raise pyxb.LogicError('completeResolution list variety with alternative %s' % (alternative,)) 4318 elif self.VARIETY_union == variety: 4319 if self._DA_union == alternative: 4320 # First time we try to resolve, create the member type 4321 # definitions. If something later prevents us from resolving 4322 # this type, we don't want to create them again, because we 4323 # might already have references to them. 4324 if self.__memberTypeDefinitions is None: 4325 mtd = [] 4326 # If present, first extract names from memberTypes, 4327 # and add each one to the list 4328 if self.__memberTypesAttribute is not None: 4329 for mn in self.__memberTypesAttribute.split(): 4330 # THROW if type has not been defined 4331 mn_en = self._namespaceContext().interpretQName(mn) 4332 std = mn_en.typeDefinition() 4333 if std is None: 4334 raise pyxb.SchemaValidationError('Unable to locate member type %s' % (mn_en,)) 4335 # Note: We do not need these to be resolved (here) 4336 assert isinstance(std, SimpleTypeDefinition) 4337 mtd.append(std) 4338 # Now look for local type definitions 4339 mtd.extend(self.__localMemberTypes) 4340 self.__memberTypeDefinitions = mtd 4341 assert None not in self.__memberTypeDefinitions 4342 4343 # Replace any member types that are themselves unions with the 4344 # members of those unions, in order. Note that doing this 4345 # might indicate we can't resolve this type yet, which is why 4346 # we separated the member list creation and the substitution 4347 # phases 4348 mtd = [] 4349 for mt in self.__memberTypeDefinitions: 4350 assert isinstance(mt, SimpleTypeDefinition) 4351 if not mt.isResolved(): 4352 self._queueForResolution('member type not resolved') 4353 return self 4354 if self.VARIETY_union == mt.variety(): 4355 mtd.extend(mt.memberTypeDefinitions()) 4356 else: 4357 mtd.append(mt) 4358 elif self._DA_restriction == alternative: 4359 assert self.__baseTypeDefinition 4360 # Base type should have been resolved before we got here 4361 assert self.__baseTypeDefinition.isResolved() 4362 mtd = self.__baseTypeDefinition.__memberTypeDefinitions 4363 assert mtd is not None 4364 else: 4365 raise pyxb.LogicError('completeResolution union variety with alternative %s' % (alternative,)) 4366 # Save a unique copy 4367 self.__memberTypeDefinitions = mtd[:] 4368 else: 4369 raise pyxb.LogicError('completeResolution with variety 0x%02x' % (variety,)) 4370 4371 # Determine what facets, if any, apply to this type. This 4372 # should only do something if this is a primitive type. 4373 self.__processHasFacetAndProperty(variety) 4374 self.__updateFacets(body) 4375 4376 self.__derivationAlternative = alternative 4377 self.__variety = variety 4378 self.__domNode = None 4379 #print 'Completed STD %s' % (self,) 4380 return self
4381
4382 - def isResolved (self):
4383 """Indicate whether this simple type is fully defined. 4384 4385 Type resolution for simple types means that the corresponding 4386 schema component fields have been set. Specifically, that 4387 means variety, baseTypeDefinition, and the appropriate 4388 additional fields depending on variety. See _resolve() for 4389 more information. 4390 """ 4391 # Only unresolved nodes have an unset variety 4392 return (self.__variety is not None)
4393 4394 # STD:res
4395 - def _resolve (self):
4396 """Attempt to resolve the type. 4397 4398 Type resolution for simple types means that the corresponding 4399 schema component fields have been set. Specifically, that 4400 means variety, baseTypeDefinition, and the appropriate 4401 additional fields depending on variety. 4402 4403 All built-in STDs are resolved upon creation. Schema-defined 4404 STDs are held unresolved until the schema has been completely 4405 read, so that references to later schema-defined STDs can be 4406 resolved. Resolution is performed after the entire schema has 4407 been scanned and STD instances created for all 4408 topLevelSimpleTypes. 4409 4410 If a built-in STD is also defined in a schema (which it should 4411 be for XMLSchema), the built-in STD is kept, with the 4412 schema-related information copied over from the matching 4413 schema-defined STD. The former then replaces the latter in 4414 the list of STDs to be resolved. 4415 4416 Types defined by restriction have the same variety as the type 4417 they restrict. If a simple type restriction depends on an 4418 unresolved type, this method simply queues it for resolution 4419 in a later pass and returns. 4420 """ 4421 if self.__variety is not None: 4422 return self 4423 #print 'Resolving STD %s' % (self.name(),) 4424 assert self.__domNode 4425 node = self.__domNode 4426 4427 kw = { 'owner' : self 4428 , 'schema' : self._schema() } 4429 4430 bad_instance = False 4431 # The guts of the node should be exactly one instance of 4432 # exactly one of these three types. 4433 candidate = LocateUniqueChild(node, 'list') 4434 if candidate: 4435 self.__initializeFromList(candidate, **kw) 4436 4437 candidate = LocateUniqueChild(node, 'restriction') 4438 if candidate: 4439 if self.__variety is None: 4440 self.__initializeFromRestriction(candidate, **kw) 4441 else: 4442 bad_instance = True 4443 4444 candidate = LocateUniqueChild(node, 'union') 4445 if candidate: 4446 if self.__variety is None: 4447 self.__initializeFromUnion(candidate, **kw) 4448 else: 4449 bad_instance = True 4450 4451 if self.__baseTypeDefinition is None: 4452 raise pyxb.SchemaValidationError('xs:simpleType must have list, union, or restriction as child') 4453 4454 if self._schema() is not None: 4455 self.__final = self._schema().finalForNode(node, self._STD_Map) 4456 4457 # It is NOT an error to fail to resolve the type. 4458 if bad_instance: 4459 raise pyxb.SchemaValidationError('Expected exactly one of list, restriction, union as child of simpleType') 4460 4461 return self
4462 4463 # CFD:STD CFD:SimpleTypeDefinition 4464 @classmethod
4465 - def CreateFromDOM (cls, node, **kw):
4466 # Node should be an XMLSchema simpleType node 4467 assert xsd.nodeIsNamed(node, 'simpleType') 4468 4469 name = NodeAttribute(node, 'name') 4470 4471 rv = cls(name=name, node=node, variety=None, **kw) 4472 rv._annotationFromDOM(node) 4473 4474 # Creation does not attempt to do resolution. Queue up the newly created 4475 # whatsis so we can resolve it after everything's been read in. 4476 rv.__domNode = node 4477 rv._queueForResolution('creation') 4478 4479 return rv
4480 4481 # pythonSupport is None, or a subclass of datatypes.simpleTypeDefinition. 4482 # When set, this simple type definition instance must be uniquely 4483 # associated with the python support type. 4484 __pythonSupport = None 4485
4486 - def _setPythonSupport (self, python_support):
4487 # Includes check that python_support is not None 4488 assert issubclass(python_support, basis.simpleTypeDefinition) 4489 # Can't share support instances 4490 self.__pythonSupport = python_support 4491 self.__pythonSupport._SimpleTypeDefinition(self) 4492 if self.nameInBinding() is None: 4493 self.setNameInBinding(self.__pythonSupport.__name__) 4494 return self.__pythonSupport
4495
4496 - def hasPythonSupport (self):
4497 return self.__pythonSupport is not None
4498
4499 - def pythonSupport (self):
4500 if self.__pythonSupport is None: 4501 raise pyxb.LogicError('%s: No support defined' % (self.name(),)) 4502 return self.__pythonSupport
4503
4504 - def stringToPython (self, string):
4505 return self.pythonSupport().stringToPython(string)
4506
4507 - def pythonToString (self, value):
4508 return self.pythonSupport().pythonToString(value)
4509
4510 -class _SimpleUrTypeDefinition (SimpleTypeDefinition, _Singleton_mixin):
4511 """Subclass ensures there is only one simple ur-type.""" 4512 pass
4513
4514 -class _ImportElementInformationItem (_Annotated_mixin):
4515 """Data associated with an 4516 U{import<http://www.w3.org/TR/xmlschema-1/#composition-schemaImport>} 4517 statement within a schema.""" 4518
4519 - def id (self):
4520 """The value of the C{id} attribute from the import statement.""" 4521 return self.__id
4522 __id = None 4523
4524 - def namespace (self):
4525 """The L{pyxb.namespace.Namespace} instance corresponding to the value 4526 of the C{namespace} attribute from the import statement.""" 4527 return self.__namespace
4528 __namespace = None 4529
4530 - def schemaLocation (self):
4531 """The value of the C{schemaLocation} attribute from the import 4532 statement, normalized relative to the location of the importing 4533 schema.""" 4534 return self.__schemaLocation
4535 __schemaLocation = None 4536
4537 - def prefix (self):
4538 """The prefix from a namespace declaration for L{namespace} that was 4539 active in the context of the import element, or C{None} if there was 4540 no relevant namespace declaration in scope at that point. 4541 4542 This is propagated to be used as the default prefix for the 4543 corresponding namespace if no prefix had been assigned. 4544 """ 4545 return self.__prefix
4546 __prefix = None 4547
4548 - def schema (self):
4549 """The L{Schema} instance corresponding to the imported schema, if 4550 available. 4551 4552 Normally C{import} statements will be fulfilled by loading components 4553 from a L{namespace archive<pyxb.namespace.NamespaceArchive>} in which 4554 the corresponding namespace is marked as public. Where there are 4555 cycles in the namespace dependency graph, or the schema for a 4556 namespace are associated with a restricted profile of another 4557 namespace, there may be no such archive and instead the components are 4558 obtained using this schema.""" 4559 return self.__schema
4560 __schema = None 4561
4562 - def __init__ (self, importing_schema, node, **kw):
4563 """Gather the information relative to an C{import} statement. 4564 4565 This examines the L{available 4566 namespaces<pyxb.namespace.archive.AvailableForLoad>} to see whether 4567 the imported namespace can be loaded. If so, the C{schemaLocation} 4568 attribute is ignored. Otherwise, it attempts to retrieve and parse 4569 the corresponding schema (if this has not already been done). 4570 4571 @param importing_schema: The L{Schema} instance in which the import 4572 was found. 4573 @param node: The C{xml.dom.DOM} node incorporating the schema 4574 information. 4575 4576 @raise Exception: Any exception raised when attempting to retrieve and 4577 parse data from the schema location. 4578 """ 4579 4580 super(_ImportElementInformationItem, self).__init__(**kw) 4581 uri = NodeAttribute(node, 'namespace') 4582 if uri is None: 4583 raise pyxb.IncompleteImplementationError('import statements without namespace not supported') 4584 schema_location = pyxb.utils.utility.NormalizeLocation(NodeAttribute(node, 'schemaLocation'), importing_schema.location()) 4585 self.__schemaLocation = schema_location 4586 ns = self.__namespace = pyxb.namespace.NamespaceForURI(uri, create_if_missing=True) 4587 need_schema = not (ns.isLoadable() or ns.isBuiltinNamespace()) 4588 if not need_schema: 4589 # Discard location if we expect to be able to learn about this 4590 # namespace from an archive or a built-in description 4591 self.__schemaLocation = None 4592 4593 ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(node) 4594 if self.schemaLocation() is not None: 4595 # @todo: NOTICE 4596 # print 'import %s + %s = %s' % (importing_schema.location(), self.__schemaLocation, schema_location) 4597 (has_schema, schema_instance) = self.__namespace.lookupSchemaByLocation(schema_location) 4598 if not has_schema: 4599 ckw = { 'absolute_schema_location' : schema_location, 4600 'generation_uid' : importing_schema.generationUID(), 4601 'uri_content_archive_directory' : importing_schema._uriContentArchiveDirectory(), 4602 } 4603 try: 4604 schema_instance = Schema.CreateFromLocation(**ckw) 4605 except Exception, e: 4606 print 'WARNING: Import %s cannot read schema location %s (%s): %s' % (ns, self.__schemaLocation, schema_location, e) 4607 raise 4608 self.__schema = schema_instance 4609 elif need_schema: 4610 print 'WARNING: No information available on imported namespace %s' % (uri,) 4611 4612 # If we think we found a schema, make sure it's in the right 4613 # namespace. 4614 if self.__schema is not None: 4615 if ns != self.__schema.targetNamespace(): 4616 raise pyxb.SchemaValidationError('Import expected namespace %s but got %s' % (ns, self.__schema.targetNamespace())) 4617 4618 self.__prefix = ns_ctx.prefixForNamespace(self.namespace()) 4619 4620 self._annotationFromDOM(node)
4621
4622 -class Schema (_SchemaComponent_mixin):
4623 """An XMLSchema U{Schema<http://www.w3.org/TR/xmlschema-1/#Schemas>}.""" 4624
4625 - def __getstate__ (self):
4626 raise pyxb.LogicError('Attempt to serialize Schema instance')
4627 4628 # List of annotations 4629 __annotations = None 4630 4631 # True when we have started seeing elements, attributes, or 4632 # notations. 4633 __pastProlog = False 4634
4635 - def location (self):
4636 """URI or path to where the schema can be found. 4637 4638 For schema created by a user, the location should be provided to the 4639 constructor using the C{schema_location} keyword. In the case of 4640 imported or included schema, the including schema's location is used 4641 as the base URI for determining the absolute URI of the included 4642 schema from its (possibly relative) location value. For files, 4643 the scheme and authority portions are generally absent, as is often 4644 the abs_path part.""" 4645 return self.__location
4646 __location = None 4647
4648 - def locationTag (self):
4649 return self.__locationTag
4650 __locationTag = None 4651
4652 - def signature (self):
4653 return self.__signature
4654 __signature = None 4655
4656 - def generationUID (self):
4657 return self.__generationUID
4658 __generationUID = None 4659
4660 - def originRecord (self):
4661 return self.__originRecord
4662 __originRecord = None 4663
4664 - def targetNamespace (self):
4665 """The targetNamespace of a componen. 4666 4667 This is None, or a reference to a Namespace in which the 4668 component is declared (either as a global or local to one of 4669 the namespace's complex type definitions). This is immutable 4670 after creation. 4671 """ 4672 return self.__targetNamespace
4673 __targetNamespace = None 4674
4675 - def defaultNamespace (self):
4676 """Default namespace of the schema. 4677 4678 Will be None unless the schema has an 'xmlns' attribute. The 4679 value must currently be provided as a keyword parameter to the 4680 constructor. """ 4681 return self.__defaultNamespace
4682 __defaultNamespace = None 4683
4684 - def referencedNamespaces (self):
4685 return self.__referencedNamespaces
4686 __referencedNamespaces = None 4687
4688 - def importEIIs (self):
4689 return self.__importEIIs
4690 __importEIIs = None 4691
4692 - def importedSchema (self):
4693 return self.__importedSchema
4694 __importedSchema = None
4695 - def includedSchema (self):
4696 return self.__includedSchema
4697 __includedSchema = None 4698 4699 _QUALIFIED = "qualified" 4700 _UNQUALIFIED = "unqualified" 4701 4702 # Default values for standard recognized schema attributes 4703 __attributeMap = { pyxb.namespace.ExpandedName(None, 'attributeFormDefault') : _UNQUALIFIED 4704 , pyxb.namespace.ExpandedName(None, 'elementFormDefault') : _UNQUALIFIED 4705 , pyxb.namespace.ExpandedName(None, 'blockDefault') : '' 4706 , pyxb.namespace.ExpandedName(None, 'finalDefault') : '' 4707 , pyxb.namespace.ExpandedName(None, 'id') : None 4708 , pyxb.namespace.ExpandedName(None, 'targetNamespace') : None 4709 , pyxb.namespace.ExpandedName(None, 'version') : None 4710 , pyxb.namespace.XML.createExpandedName('lang') : None 4711 } 4712
4713 - def _setAttributeFromDOM (self, attr):
4714 """Override the schema attribute with the given DOM value.""" 4715 self.__attributeMap[pyxb.namespace.ExpandedName(attr.name)] = attr.nodeValue 4716 return self
4717
4718 - def _setAttributesFromMap (self, attr_map):
4719 """Override the schema attributes with values from the given map.""" 4720 self.__attributeMap.update(attr_map) 4721 return self
4722
4723 - def schemaHasAttribute (self, attr_name):
4724 """Return True iff the schema has an attribute with the given (nc)name.""" 4725 if isinstance(attr_name, basestring): 4726 attr_name = pyxb.namespace.ExpandedName(None, attr_name) 4727 return self.__attributeMap.has_key(attr_name)
4728
4729 - def schemaAttribute (self, attr_name):
4730 """Return the schema attribute value associated with the given (nc)name. 4731 4732 @param attr_name: local name for the attribute in the schema element. 4733 @return: the value of the corresponding attribute, or C{None} if it 4734 has not been defined and has no default. 4735 @raise KeyError: C{attr_name} is not a valid attribute for a C{schema} element. 4736 """ 4737 if isinstance(attr_name, basestring): 4738 attr_name = pyxb.namespace.ExpandedName(None, attr_name) 4739 return self.__attributeMap[attr_name]
4740 4741 __SchemaCategories = ( 'typeDefinition', 'attributeGroupDefinition', 'modelGroupDefinition', 4742 'attributeDeclaration', 'elementDeclaration', 'notationDeclaration', 4743 'identityConstraintDefinition' ) 4744
4745 - def _uriContentArchiveDirectory (self):
4747 __uriContentArchiveDirectory = None 4748
4749 - def __init__ (self, *args, **kw):
4750 # Force resolution of available namespaces if not already done 4751 if not kw.get('_bypass_preload', False): 4752 pyxb.namespace.archive.NamespaceArchive.PreLoadArchives() 4753 4754 assert 'schema' not in kw 4755 self.__uriContentArchiveDirectory = kw.get('uri_content_archive_directory') 4756 self.__location = kw.get('schema_location') 4757 if self.__location is not None: 4758 schema_path = self.__location 4759 if 0 <= schema_path.find(':'): 4760 schema_path = urlparse.urlparse(schema_path)[2] # .path 4761 self.__locationTag = os.path.split(schema_path)[1].split('.')[0] 4762 4763 self.__generationUID = kw.get('generation_uid') 4764 if self.__generationUID is None: 4765 print 'WARNING: No generationUID provided' 4766 self.__generationUID = pyxb.utils.utility.UniqueIdentifier() 4767 4768 self.__signature = kw.get('schema_signature') 4769 #print 'Schema at %s signature %s uid %s' % (self.location(), self.signature(), self.generationUID()) 4770 4771 super(Schema, self).__init__(*args, **kw) 4772 self.__importEIIs = set() 4773 self.__includedSchema = set() 4774 self.__importedSchema = set() 4775 self.__targetNamespace = self._namespaceContext().targetNamespace() 4776 if not isinstance(self.__targetNamespace, pyxb.namespace.Namespace): 4777 raise pyxb.LogicError('Schema constructor requires valid Namespace instance as target_namespace') 4778 4779 # NB: This will raise pyxb.SchemaUniquenessError if it appears this 4780 # schema has already been incorporated into the target namespace. 4781 self.__originRecord = self.__targetNamespace.addSchema(self) 4782 4783 self.__targetNamespace.configureCategories(self.__SchemaCategories) 4784 if self.__defaultNamespace is not None: 4785 self.__defaultNamespace.configureCategories(self.__SchemaCategories) 4786 4787 self.__attributeMap = self.__attributeMap.copy() 4788 self.__annotations = [] 4789 # @todo: This isn't right if namespaces are introduced deeper in the document 4790 self.__referencedNamespaces = self._namespaceContext().inScopeNamespaces().values()
4791 4792 __TopLevelComponentMap = { 4793 'element' : ElementDeclaration, 4794 'attribute' : AttributeDeclaration, 4795 'notation' : NotationDeclaration, 4796 'simpleType' : SimpleTypeDefinition, 4797 'complexType' : ComplexTypeDefinition, 4798 'group' : ModelGroupDefinition, 4799 'attributeGroup' : AttributeGroupDefinition 4800 } 4801 4802 @classmethod
4803 - def CreateFromDocument (cls, xmls, **kw):
4804 if not ('schema_signature' in kw): 4805 kw['schema_signature'] = pyxb.utils.utility.HashForText(xmls) 4806 return cls.CreateFromDOM(StringToDOM(xmls, **kw), **kw)
4807 4808 @classmethod
4809 - def CreateFromLocation (cls, **kw):
4810 """Create a schema from a schema location. 4811 4812 Reads an XML document from the schema location and creates a schema 4813 using it. All keyword parameters are passed to L{CreateFromDOM}. 4814 4815 @keyword schema_location: A file path or a URI. If this is a relative 4816 URI and C{parent_uri} is present, the actual location will be 4817 L{normallzed<pyxb.utils.utility.NormalizeLocation>}. 4818 @keyword parent_uri: The context within which schema_location will be 4819 normalized, if necessary. 4820 @keyword absolute_schema_location: A file path or URI. This value is 4821 not normalized, and supersedes C{schema_location}. 4822 """ 4823 schema_location = kw.pop('absolute_schema_location', pyxb.utils.utility.NormalizeLocation(kw.get('schema_location'), kw.get('parent_uri'))) 4824 kw['location_base'] = kw['schema_location'] = schema_location 4825 assert isinstance(schema_location, basestring), 'Unexpected value %s type %s for schema_location' % (schema_location, type(schema_location)) 4826 uri_content_archive_directory = kw.get('uri_content_archive_directory') 4827 return cls.CreateFromDocument(pyxb.utils.utility.TextFromURI(schema_location, archive_directory=uri_content_archive_directory), **kw)
4828 4829 @classmethod
4830 - def CreateFromStream (cls, stream, **kw):
4831 return cls.CreateFromDocument(stream.read(), **kw)
4832 4833 @classmethod
4834 - def CreateFromDOM (cls, node, namespace_context=None, schema_location=None, schema_signature=None, generation_uid=None, **kw):
4835 """Take the root element of the document, and scan its attributes under 4836 the assumption it is an XMLSchema schema element. That means 4837 recognize namespace declarations and process them. Also look for 4838 and set the default namespace. All other attributes are passed up 4839 to the parent class for storage.""" 4840 4841 # Get the context of any schema that is including (not importing) this 4842 # one. 4843 including_context = kw.get('including_context') 4844 4845 root_node = node 4846 if Node.DOCUMENT_NODE == node.nodeType: 4847 root_node = root_node.documentElement 4848 if Node.ELEMENT_NODE != root_node.nodeType: 4849 raise pyxb.LogicError('Must be given a DOM node of type ELEMENT') 4850 4851 assert (namespace_context is None) or isinstance(namespace_context, pyxb.namespace.resolution.NamespaceContext) 4852 ns_ctx = pyxb.namespace.resolution.NamespaceContext.GetNodeContext(root_node, 4853 parent_context=namespace_context, 4854 including_context=including_context) 4855 4856 tns = ns_ctx.targetNamespace() 4857 if tns is None: 4858 raise pyxb.SchemaValidationError('No targetNamespace associated with content (not a schema?)') 4859 schema = cls(namespace_context=ns_ctx, schema_location=schema_location, schema_signature=schema_signature, generation_uid=generation_uid, **kw) 4860 schema.__namespaceData = ns_ctx 4861 4862 if schema.targetNamespace() != ns_ctx.targetNamespace(): 4863 raise pyxb.SchemaValidationError('targetNamespace %s conflicts with %s' % (schema.targetNamespace(), ns_ctx.targetNamespace())) 4864 4865 # Update the attribute map 4866 for ai in range(root_node.attributes.length): 4867 schema._setAttributeFromDOM(root_node.attributes.item(ai)) 4868 4869 # Verify that the root node is an XML schema element 4870 if not xsd.nodeIsNamed(root_node, 'schema'): 4871 raise pyxb.SchemaValidationError('Root node %s of document is not an XML schema element' % (root_node.nodeName,)) 4872 4873 for cn in root_node.childNodes: 4874 if Node.ELEMENT_NODE == cn.nodeType: 4875 rv = schema.__processTopLevelNode(cn) 4876 if rv is None: 4877 print 'Unrecognized: %s %s' % (cn.nodeName, cn.toxml()) 4878 elif Node.TEXT_NODE == cn.nodeType: 4879 # Non-element content really should just be whitespace. 4880 # If something else is seen, print it for inspection. 4881 text = cn.data.strip() 4882 if text: 4883 print 'Ignored text: %s' % (text,) 4884 elif Node.COMMENT_NODE == cn.nodeType: 4885 #print 'comment: %s' % (cn.data.strip(),) 4886 pass 4887 else: 4888 # ATTRIBUTE_NODE 4889 # CDATA_SECTION_NODE 4890 # ENTITY_NODE 4891 # PROCESSING_INSTRUCTION 4892 # DOCUMENT_NODE 4893 # DOCUMENT_TYPE_NODE 4894 # NOTATION_NODE 4895 print 'Ignoring non-element: %s' % (cn,) 4896 4897 # Do not perform resolution yet: we may be done with this schema, but 4898 # the namespace may incorporate additional ones, and we can't resolve 4899 # until everything's present. 4900 return schema
4901 4902 _SA_All = '#all' 4903
4904 - def __ebvForNode (self, attr, dom_node, candidate_map):
4905 ebv = NodeAttribute(dom_node, attr) 4906 if ebv is None: 4907 ebv = self.schemaAttribute('%sDefault' % (attr,)) 4908 rv = 0 4909 if ebv == self._SA_All: 4910 for v in candidate_map.values(): 4911 rv += v 4912 else: 4913 for candidate in ebv.split(): 4914 rv += candidate_map.get(candidate, 0) 4915 return rv
4916
4917 - def blockForNode (self, dom_node, candidate_map):
4918 """Return a bit mask indicating a set of options read from the node's "block" attribute or the schema's "blockDefault" attribute. 4919 4920 A value of '#all' means enable every options; otherwise, the attribute 4921 value should be a list of tokens, for which the corresponding value 4922 will be added to the return value. 4923 4924 @param dom_node: the node from which the "block" attribute will be retrieved 4925 @type dom_node: C{xml.dom.Node} 4926 @param candidate_map: map from strings to bitmask values 4927 """ 4928 return self.__ebvForNode('block', dom_node, candidate_map)
4929
4930 - def finalForNode (self, dom_node, candidate_map):
4931 """Return a bit mask indicating a set of options read from the node's 4932 "final" attribute or the schema's "finalDefault" attribute. 4933 4934 A value of '#all' means enable every options; otherwise, the attribute 4935 value should be a list of tokens, for which the corresponding value 4936 will be added to the return value. 4937 4938 @param dom_node: the node from which the "final" attribute will be retrieved 4939 @type dom_node: C{xml.dom.Node} 4940 @param candidate_map: map from strings to bitmask values 4941 """ 4942 return self.__ebvForNode('final', dom_node, candidate_map)
4943
4944 - def targetNamespaceForNode (self, dom_node, declaration_type):
4945 """Determine the target namespace for a local attribute or element declaration. 4946 4947 Look at the node's C{form} attribute, or if none the schema's 4948 C{attributeFormDefault} or C{elementFormDefault} value. If the 4949 resulting value is C{"qualified"} and the parent schema has a 4950 non-absent target namespace, return it to use as the declaration 4951 target namespace. Otherwise, return None to indicate that the 4952 declaration has no namespace. 4953 4954 @param dom_node: The node defining an element or attribute declaration 4955 @param declaration_type: Either L{AttributeDeclaration} or L{ElementDeclaration} 4956 @return: L{pyxb.namespace.Namespace} or None 4957 """ 4958 4959 form_type = NodeAttribute(dom_node, 'form') 4960 if form_type is None: 4961 if declaration_type == ElementDeclaration: 4962 form_type = self.schemaAttribute('elementFormDefault') 4963 elif declaration_type == AttributeDeclaration: 4964 form_type = self.schemaAttribute('attributeFormDefault') 4965 else: 4966 raise pyxb.LogicError('Expected ElementDeclaration or AttributeDeclaration: got %s' % (declaration_type,)) 4967 tns = None 4968 if (self._QUALIFIED == form_type): 4969 tns = self.targetNamespace() 4970 if tns.isAbsentNamespace(): 4971 tns = None 4972 else: 4973 if (self._UNQUALIFIED != form_type): 4974 raise pyxb.SchemaValidationError('Form type neither %s nor %s' % (self._QUALIFIED, self._UNQUALIFIED)) 4975 return tns
4976
4977 - def __requireInProlog (self, node_name):
4978 """Throw a SchemaValidationException referencing the given 4979 node if we have passed the sequence point representing the end 4980 of prolog elements.""" 4981 4982 if self.__pastProlog: 4983 print '%s past prolog' % (object.__str__(self),) 4984 raise pyxb.SchemaValidationError('Unexpected node %s after prolog' % (node_name,))
4985
4986 - def __processInclude (self, node):
4987 self.__requireInProlog(node.nodeName) 4988 # See section 4.2.1 of Structures. 4989 abs_uri = pyxb.utils.utility.NormalizeLocation(NodeAttribute(node, 'schemaLocation'), self.__location) 4990 #print 'include %s + %s = %s' % (self.__location, rel_uri, abs_uri) 4991 (has_schema, schema_instance) = self.targetNamespace().lookupSchemaByLocation(abs_uri) 4992 if not has_schema: 4993 kw = { 'absolute_schema_location': abs_uri, 4994 'including_context': self.__namespaceData, 4995 'generation_uid': self.generationUID(), 4996 'uri_content_archive_directory': self._uriContentArchiveDirectory(), 4997 } 4998 try: 4999 schema_instance = self.CreateFromLocation(**kw) 5000 except Exception, e: 5001 print 'INCLUDE %s caught: %s' % (abs_uri, e) 5002 #traceback.print_exception(*sys.exc_info()) 5003 raise 5004 # @todo: NOTICE 5005 #print '%s completed including %s from %s' % (self.__location, included_schema.targetNamespace(), abs_uri) 5006 # @todo: NOTICE 5007 #print 'Included %s, back to %s' % (included_schema.location(), self.location()) 5008 if schema_instance: 5009 if self.targetNamespace() != schema_instance.targetNamespace(): 5010 raise pyxb.SchemaValidationError('Included namespace %s not consistent with including namespace %s' % (schema_instance.targetNamespace(), self.targetNamespace())) 5011 self.__includedSchema.add(schema_instance) 5012 return node
5013
5014 - def __processImport (self, node):
5015 """Process an import directive. 5016 5017 This attempts to locate schema (named entity) information for 5018 a namespace that is referenced by this schema. 5019 """ 5020 5021 self.__requireInProlog(node.nodeName) 5022 import_eii = _ImportElementInformationItem(self, node) 5023 # @todo: NOTICE 5024 #print 'Imported %s, prefix %s, back to %s' % (import_eii.namespace().uri(), import_eii.prefix(), self.__location) 5025 if import_eii.schema() is not None: 5026 self.__importedSchema.add(import_eii.schema()) 5027 self.targetNamespace().importNamespace(import_eii.namespace()) 5028 ins = import_eii.namespace() 5029 if ins.prefix() is None: 5030 ins.setPrefix(import_eii.prefix()) 5031 self.__importEIIs.add(import_eii) 5032 return node
5033
5034 - def __processRedefine (self, node):
5035 self.__requireInProlog(node.nodeName) 5036 raise IncompleteImplementationException('redefine not implemented')
5037
5038 - def __processAnnotation (self, node):
5039 an = self._addAnnotation(Annotation.CreateFromDOM(node)) 5040 return self
5041
5042 - def __processTopLevelNode (self, node):
5043 """Process a DOM node from the top level of the schema. 5044 5045 This should return a non-None value if the node was 5046 successfully recognized.""" 5047 if xsd.nodeIsNamed(node, 'include'): 5048 return self.__processInclude(node) 5049 if xsd.nodeIsNamed(node, 'import'): 5050 return self.__processImport(node) 5051 if xsd.nodeIsNamed(node, 'redefine'): 5052 return self.__processRedefine(node) 5053 if xsd.nodeIsNamed(node, 'annotation'): 5054 return self.__processAnnotation(node) 5055 5056 component = self.__TopLevelComponentMap.get(node.localName) 5057 if component is not None: 5058 self.__pastProlog = True 5059 kw = { 'scope' : _ScopedDeclaration_mixin.SCOPE_global, 5060 'schema' : self, 5061 'owner' : self } 5062 return self._addNamedComponent(component.CreateFromDOM(node, **kw)) 5063 5064 raise pyxb.SchemaValidationError('Unexpected top-level element %s' % (node.nodeName,))
5065
5066 - def _addAnnotation (self, annotation):
5067 self.__annotations.append(annotation) 5068 return annotation
5069
5070 - def _addNamedComponent (self, nc):
5071 tns = self.targetNamespace() 5072 assert tns is not None 5073 if not isinstance(nc, _NamedComponent_mixin): 5074 raise pyxb.LogicError('Attempt to add unnamed %s instance to dictionary' % (nc.__class__,)) 5075 if nc.isAnonymous(): 5076 raise pyxb.LogicError('Attempt to add anonymous component to dictionary: %s', (nc.__class__,)) 5077 if isinstance(nc, _ScopedDeclaration_mixin): 5078 assert _ScopedDeclaration_mixin.SCOPE_global == nc.scope() 5079 #print 'Adding %s as %s' % (nc.__class__.__name__, nc.name()) 5080 if isinstance(nc, (SimpleTypeDefinition, ComplexTypeDefinition)): 5081 return self.__addTypeDefinition(nc) 5082 if isinstance(nc, AttributeDeclaration): 5083 return self.__addAttributeDeclaration(nc) 5084 if isinstance(nc, AttributeGroupDefinition): 5085 return self.__addAttributeGroupDefinition(nc) 5086 if isinstance(nc, ModelGroupDefinition): 5087 return tns.addCategoryObject('modelGroupDefinition', nc.name(), nc) 5088 if isinstance(nc, ElementDeclaration): 5089 return tns.addCategoryObject('elementDeclaration', nc.name(), nc) 5090 if isinstance(nc, NotationDeclaration): 5091 return tns.addCategoryObject('notationDeclaration', nc.name(), nc) 5092 if isinstance(nc, IdentityConstraintDefinition): 5093 return tns.addCategoryObject('identityConstraintDefinition', nc.name(), nc) 5094 raise pyxb.IncompleteImplementationError('No support to record named component of type %s' % (nc.__class__,))
5095
5096 - def __addTypeDefinition (self, td):
5097 local_name = td.name() 5098 assert self.__targetNamespace 5099 tns = self.targetNamespace() 5100 old_td = tns.typeDefinitions().get(local_name) 5101 if (old_td is not None) and (old_td != td): 5102 if isinstance(td, ComplexTypeDefinition) != isinstance(old_td, ComplexTypeDefinition): 5103 raise pyxb.SchemaValidationError('Name %s used for both simple and complex types' % (td.name(),)) 5104 5105 if not old_td._allowUpdateFromOther(td): 5106 raise pyxb.SchemaValidationError('Attempt to re-define non-builtin type definition %s' % (tns.createExpandedName(local_name),)) 5107 5108 # Copy schema-related information from the new definition 5109 # into the old one, and continue to use the old one. 5110 td = tns._replaceComponent(td, old_td._updateFromOther(td)) 5111 else: 5112 tns.addCategoryObject('typeDefinition', td.name(), td) 5113 assert td is not None 5114 return td
5115
5116 - def __addAttributeDeclaration (self, ad):
5117 local_name = ad.name() 5118 assert self.__targetNamespace 5119 tns = self.targetNamespace() 5120 old_ad = tns.attributeDeclarations().get(local_name) 5121 if (old_ad is not None) and (old_ad != ad): 5122 if not old_ad._allowUpdateFromOther(ad): 5123 raise pyxb.SchemaValidationError('Attempt to re-define non-builtin attribute declaration %s' % (tns.createExpandedName(local_name),)) 5124 5125 # Copy schema-related information from the new definition 5126 # into the old one, and continue to use the old one. 5127 ad = tns._replaceComponent(ad, old_ad._updateFromOther(ad)) 5128 else: 5129 tns.addCategoryObject('attributeDeclaration', ad.name(), ad) 5130 assert ad is not None 5131 return ad
5132
5133 - def __addAttributeGroupDefinition (self, agd):
5134 local_name = agd.name() 5135 assert self.__targetNamespace 5136 tns = self.targetNamespace() 5137 old_agd = tns.attributeGroupDefinitions().get(local_name) 5138 if (old_agd is not None) and (old_agd != agd): 5139 if not old_agd._allowUpdateFromOther(agd): 5140 raise pyxb.SchemaValidationError('Attempt to re-define non-builtin attribute group definition %s' % (tns.createExpandedName(local_name),)) 5141 5142 # Copy schema-related information from the new definition 5143 # into the old one, and continue to use the old one. 5144 ad = tns._replaceComponent(agd, old_agd._updateFromOther(agd)) 5145 else: 5146 tns.addCategoryObject('attributeGroupDefinition', agd.name(), agd) 5147 assert agd is not None 5148 return agd
5149
5150 - def __str__ (self):
5151 return 'SCH[%s]' % (self.location(),)
5152
5153 5154 -def _AddSimpleTypes (namespace):
5155 """Add to the schema the definitions of the built-in types of XMLSchema. 5156 This should only be invoked by L{pyxb.namespace} when the built-in 5157 namespaces are initialized. """ 5158 # Add the ur type 5159 #schema = namespace.schema() 5160 schema = Schema(namespace_context=pyxb.namespace.XMLSchema.initialNamespaceContext(), schema_location='URN:noLocation:PyXB:XMLSchema', generation_uid=pyxb.namespace.BuiltInObjectUID, _bypass_preload=True) 5161 td = schema._addNamedComponent(ComplexTypeDefinition.UrTypeDefinition(schema, in_builtin_definition=True)) 5162 assert td.isResolved() 5163 # Add the simple ur type 5164 td = schema._addNamedComponent(SimpleTypeDefinition.SimpleUrTypeDefinition(schema, in_builtin_definition=True)) 5165 assert td.isResolved() 5166 # Add definitions for all primitive and derived simple types 5167 pts_std_map = {} 5168 ns_ctx = namespace.initialNamespaceContext() 5169 for dtc in datatypes._PrimitiveDatatypes: 5170 name = dtc.__name__.rstrip('_') 5171 td = schema._addNamedComponent(SimpleTypeDefinition.CreatePrimitiveInstance(name, schema, dtc)) 5172 assert td.isResolved() 5173 assert dtc.SimpleTypeDefinition() == td 5174 pts_std_map.setdefault(dtc, td) 5175 for dtc in datatypes._DerivedDatatypes: 5176 name = dtc.__name__.rstrip('_') 5177 parent_std = pts_std_map[dtc.XsdSuperType()] 5178 td = schema._addNamedComponent(SimpleTypeDefinition.CreateDerivedInstance(name, schema, parent_std, dtc)) 5179 assert td.isResolved() 5180 assert dtc.SimpleTypeDefinition() == td 5181 pts_std_map.setdefault(dtc, td) 5182 for dtc in datatypes._ListDatatypes: 5183 list_name = dtc.__name__.rstrip('_') 5184 element_name = dtc._ItemType.__name__.rstrip('_') 5185 element_std = schema.targetNamespace().typeDefinitions().get(element_name) 5186 assert element_std is not None 5187 td = schema._addNamedComponent(SimpleTypeDefinition.CreateListInstance(list_name, schema, element_std, dtc)) 5188 assert td.isResolved() 5189 global _PastAddBuiltInTypes 5190 _PastAddBuiltInTypes = True 5191 5192 return schema
5193 5194 import sys 5195 import pyxb.namespace.builtin 5196 pyxb.namespace.builtin._InitializeBuiltinNamespaces(sys.modules[__name__]) 5197 5198 ## Local Variables: 5199 ## fill-column:78 5200 ## End: 5201