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

# Source Code for Module pyxb.xmlschema.structures

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