Package pyxb :: Package binding :: Module content |
[hide private]
[frames] | no frames]

# Source Code for Module pyxb.binding.content

       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  """Helper classes that maintain the content model of XMLSchema in the binding
      17  classes.
      18
      19  L{AttributeUse} and L{ElementDeclaration} record information associated with a binding
      20  class, for example the types of values, the original XML QName or NCName, and
      21  the Python field in which the values are stored.  They also provide the
      22  low-level interface to set and get the corresponding values in a binding
      23  instance.
      24
      25  L{Wildcard} holds content-related information used in the content model.
      26  """
      27
      28  import pyxb
      29  import pyxb.namespace
      30  import pyxb.utils.fac
      31  from pyxb.binding import basis
      32  import pyxb.utils.utility
      33
      34  import xml.dom
      35  import logging
      36
      37  _log = logging.getLogger(__name__)
      38
      39 -class AttributeUse (pyxb.cscRoot):
      40      """A helper class that encapsulates everything we need to know
      41      about the way an attribute is used within a binding class.
      42
      43      Attributes are stored internally as pairs C{(provided, value)}, where
      44      C{provided} is a boolean indicating whether a value for the attribute was
      45      provided externally, and C{value} is an instance of the attribute
      46      datatype.  The C{provided} flag is used to determine whether an XML
      47      attribute should be added to a created DOM node when generating the XML
      48      corresponding to a binding instance.
      49      """
      50
      51      __name = None
      52      """ExpandedName of the attribute"""
      53
      54      __id = None
      55      """Identifier used for this attribute within the owning class"""
      56
      57      __key = None
      58      """Private Python attribute used in instances to hold the attribute value"""
      59
      60      __dataType = None
      61      """The L{pyxb.binding.basis.simpleTypeDefinition} for values of the attribute"""
      62
      63      __unicodeDefault = None
      64      """The default attribute value as a unicode string, or C{None}"""
      65
      66      __defaultValue = None
      67      """The default value as an instance of L{__dataType}, or C{None}"""
      68
      69      __fixed = False
      70      """C{True} if the attribute value cannot be changed"""
      71
      72      __required = False
      73      """C{True} if the attribute must appear in every instance of the type"""
      74
      75      __prohibited = False
      76      """C{True} if the attribute must not appear in any instance of the type"""
      77
      78 -    def __init__ (self, name, id, key, data_type, unicode_default=None, fixed=False, required=False, prohibited=False):
      79          """Create an AttributeUse instance.
      80
      81          @param name: The name by which the attribute is referenced in the XML
      82          @type name: L{pyxb.namespace.ExpandedName}
      83
      84          @param id: The Python identifier for the attribute within the
      85          containing L{pyxb.basis.binding.complexTypeDefinition}.  This is a
      86          public identifier, derived from the local part of the attribute name
      87          and modified to be unique, and is usually used as the name of the
      88          attribute's inspector method.
      89          @type id: C{str}
      90
      91          @param key: The string used to store the attribute
      92          value in the dictionary of the containing
      93          L{pyxb.basis.binding.complexTypeDefinition}.  This is mangled so
      94          that it is unique among and is treated as a Python private member.
      95          @type key: C{str}
      96
      97          @param data_type: The class reference to the subclass of
      98          L{pyxb.binding.basis.simpleTypeDefinition} of which the attribute
      99          values must be instances.
     100          @type data_type: C{type}
     101
     102          @keyword unicode_default: The default value of the attribute as
     103          specified in the schema, or None if there is no default attribute
     104          value.  The default value (of the keyword) is C{None}.
     105          @type unicode_default: C{unicode}
     106
     107          @keyword fixed: If C{True}, indicates that the attribute, if present,
     108          must have the value that was given via C{unicode_default}.  The
     109          default value is C{False}.
     110          @type fixed: C{bool}
     111
     112          @keyword required: If C{True}, indicates that the attribute must appear
     113          in the DOM node used to create an instance of the corresponding
     114          L{pyxb.binding.basis.complexTypeDefinition}.  The default value is
     115          C{False}.  No more that one of L{required} and L{prohibited} should be
     116          assigned C{True}.
     117          @type required: C{bool}
     118
     119          @keyword prohibited: If C{True}, indicates that the attribute must
     120          B{not} appear in the DOM node used to create an instance of the
     121          corresponding L{pyxb.binding.basis.complexTypeDefinition}.  The
     122          default value is C{False}.  No more that one of L{required} and
     123          L{prohibited} should be assigned C{True}.
     124          @type prohibited: C{bool}
     125
     126          @raise pyxb.SimpleTypeValueError: the L{unicode_default} cannot be used
     127          to initialize an instance of L{data_type}
     128          """
     129
     130          self.__name = name
     131          self.__id = id
     132          self.__key = key
     133          self.__dataType = data_type
     134          self.__unicodeDefault = unicode_default
     135          if self.__unicodeDefault is not None:
     136              self.__defaultValue = self.__dataType.Factory(self.__unicodeDefault, _from_xml=True)
     137          self.__fixed = fixed
     138          self.__required = required
     139          self.__prohibited = prohibited
     140          super(AttributeUse, self).__init__()
     141
     142 -    def name (self):
     143          """The expanded name of the element.
     144
     145          @rtype: L{pyxb.namespace.ExpandedName}
     146          """
     147          return self.__name
     148
     149 -    def defaultValue (self):
     150          """The default value of the attribute."""
     151          return self.__defaultValue
     152
     153 -    def fixed (self):
     154          """C{True} iff the value of the attribute cannot be changed."""
     155          return self.__fixed
     156
     157 -    def required (self):
     158          """C{True} iff the attribute must be assigned a value."""
     159          return self.__required
     160
     161 -    def prohibited (self):
     162          """C{True} iff the attribute must not be assigned a value."""
     163          return self.__prohibited
     164
     165 -    def provided (self, ctd_instance):
     166          """C{True} iff the given instance has been explicitly given a value
     167          for the attribute.
     168
     169          This is used for things like only generating an XML attribute
     170          assignment when a value was originally given (even if that value
     171          happens to be the default).
     172          """
     173          return self.__getProvided(ctd_instance)
     174
     175 -    def id (self):
     176          """Tag used within Python code for the attribute.
     177
     178          This is not used directly in the default code generation template."""
     179          return self.__id
     180
     181 -    def key (self):
     182          """String used as key within object dictionary when storing attribute value."""
     183          return self.__key
     184
     185 -    def dataType (self):
     186          """The subclass of L{pyxb.binding.basis.simpleTypeDefinition} of which any attribute value must be an instance."""
     187          return self.__dataType
     188
     189 -    def __getValue (self, ctd_instance):
     190          """Retrieve the value information for this attribute in a binding instance.
     191
     192          @param ctd_instance: The instance object from which the attribute is to be retrieved.
     193          @type ctd_instance: subclass of L{pyxb.binding.basis.complexTypeDefinition}
     194          @return: C{(provided, value)} where C{provided} is a C{bool} and
     195          C{value} is C{None} or an instance of the attribute's datatype.
     196
     197          """
     198          return getattr(ctd_instance, self.__key, (False, None))
     199
     200 -    def __getProvided (self, ctd_instance):
     201          return self.__getValue(ctd_instance)[0]
     202
     203 -    def value (self, ctd_instance):
     204          """Get the value of the attribute from the instance."""
     205          if self.__prohibited:
     206              raise pyxb.ProhibitedAttributeError(type(ctd_instance), self.__name, ctd_instance)
     207          return self.__getValue(ctd_instance)[1]
     208
     209 -    def __setValue (self, ctd_instance, new_value, provided):
     210          return setattr(ctd_instance, self.__key, (provided, new_value))
     211
     212 -    def reset (self, ctd_instance):
     213          """Set the value of the attribute in the given instance to be its
     214          default value, and mark that it has not been provided."""
     215          self.__setValue(ctd_instance, self.__defaultValue, False)
     216
     217 -    def addDOMAttribute (self, dom_support, ctd_instance, element):
     218          """If this attribute as been set, add the corresponding attribute to the DOM element."""
     219          ( provided, value ) = self.__getValue(ctd_instance)
     220          if provided:
     221              assert value is not None
     222              dom_support.addAttribute(element, self.__name, value.xsdLiteral())
     223          return self
     224
     225 -    def validate (self, ctd_instance):
     226          """Validate the instance against the requirements imposed by this
     227          attribute use.
     228
     229          There is no return value; calls raise an exception if the content does
     230          not validate.
     231
     232          @param ctd_instance : An instance of a complex type definition.
     233
     234          @raise pyxb.ProhibitedAttributeError: when instance has attribute but must not
     235          @raise pyxb.MissingAttributeError: when instance lacks attribute but
     236          must have it (including when a required fixed-value attribute is
     237          missing).
     238          @raise pyxb.BatchContentValidationError: when instance has attribute but its value is not acceptable
     239          """
     240          (provided, value) = self.__getValue(ctd_instance)
     241          if value is not None:
     242              if self.__prohibited:
     243                  raise pyxb.ProhibitedAttributeError(type(ctd_instance), self.__name, ctd_instance)
     244              if self.__required and not provided:
     245                  assert self.__fixed
     246                  raise pyxb.MissingAttributeError(type(ctd_instance), self.__name, ctd_instance)
     247              self.__dataType._CheckValidValue(value)
     248              self.__dataType.XsdConstraintsOK(value)
     249          else:
     250              if self.__required:
     251                  raise pyxb.MissingAttributeError(type(ctd_instance), self.__name, ctd_instance)
     252
     253 -    def set (self, ctd_instance, new_value, from_xml=False):
     254          """Set the value of the attribute.
     255
     256          This validates the value against the data type, creating a new instance if necessary.
     257
     258          @param ctd_instance: The binding instance for which the attribute
     259          value is to be set
     260          @type ctd_instance: subclass of L{pyxb.binding.basis.complexTypeDefinition}
     261          @param new_value: The value for the attribute
     262          @type new_value: Any value that is permitted as the input parameter to
     263          the C{Factory} method of the attribute's datatype.
     264          @param from_xml: Value C{True} iff the new_value is known to be in
     265          lexical space and must by converted by the type factory.  If C{False}
     266          (default) the value is only converted if it is not already an instance
     267          of the attribute's underlying type.
     268          """
     269          provided = True
     270          assert not isinstance(new_value, xml.dom.Node)
     271          if new_value is None:
     272              if self.__required:
     273                  raise pyxb.MissingAttributeError(type(ctd_instance), self.__name, ctd_instance)
     274              provided = False
     275          if self.__prohibited:
     276              raise pyxb.ProhibitedAttributeError(type(ctd_instance), self.__name, ctd_instance)
     277          if (new_value is not None) and (from_xml or not isinstance(new_value, self.__dataType)):
     278              new_value = self.__dataType.Factory(new_value, _from_xml=from_xml)
     279          if self.__fixed and (new_value != self.__defaultValue):
     280              raise pyxb.AttributeChangeError(type(ctd_instance), self.__name, ctd_instance)
     281          self.__setValue(ctd_instance, new_value, provided)
     282          return new_value
     283
     284 -    def _description (self, name_only=False, user_documentation=True):
     285          if name_only:
     286              return unicode(self.__name)
     287          assert issubclass(self.__dataType, basis._TypeBinding_mixin)
     288          desc = [ unicode(self.__id), ': ', unicode(self.__name), ' (', self.__dataType._description(name_only=True, user_documentation=False), '), ' ]
     289          if self.__required:
     290              desc.append('required')
     291          elif self.__prohibited:
     292              desc.append('prohibited')
     293          else:
     294              desc.append('optional')
     295          if self.__defaultValue is not None:
     296              desc.append(', ')
     297              if self.__fixed:
     298                  desc.append('fixed')
     299              else:
     300                  desc.append('default')
     301              desc.extend(['=', self.__unicodeDefault ])
     302          return ''.join(desc)
     303
     304 -class AutomatonConfiguration (object):
     305      """State for a L{pyxb.utils.fac.Automaton} monitoring content for an
     306      incrementally constructed complex type binding instance.
     307
     308      @warning: This is not an implementation of
     309      L{pyxb.utils.fac.Configuration_ABC} because we need the L{step} function
     310      to return a different type of value."""
     311
     312      # The binding instance for which content is being built
     313      __instance = None
     314
     315      # The underlying configuration when the state is deterministic.  In this
     316      # case, all updates to the instance content corresponding to the current
     317      # state have been applied to the instance.  Note that while steps are
     318      # occurring this instance, as well as those in __multi, might be
     319      # references to sub-automata.
     320      __cfg = None
     321
     322      # A list of pairs when the state is non-deterministic.  The first member
     323      # of the pair is the configuration; the second is a tuple of closures that
     324      # must be applied to the instance in order to store the content that was
     325      # accepted along the path to that configuration.  This is in order of
     326      # preference based on the location of path candidate declarations in the
     327      # defining schema.
     328      __multi = None
     329
     330 -    def __init__ (self, instance):
     331          self.__instance = instance
     332
     333 -    def reset (self):
     334          """Reset the automaton to its initial state.
     335
     336          Subsequent transitions are expected based on candidate content to be
     337          supplied through the L{step} method."""
     338          self.__cfg = self.__instance._Automaton.newConfiguration()
     339          self.__multi = None
     340
     341 -    def nondeterminismCount (self):
     342          """Return the number of pending configurations.
     343
     344          The automaton is deterministic if exactly one configuration is
     345          available."""
     346          if self.__cfg is not None:
     347              assert self.__multi is None
     348              return 1
     349          return len(self.__multi)
     350
     351 -    def step (self, value, element_decl):
     352          """Attempt a transition from the current state.
     353
     354          @param value: the content to be supplied.  For success the value must
     355          be consistent with the recorded symbol (element or wildcard
     356          declaration) for a transition from the current automaton state.
     357
     358          @param element_decl: optional
     359          L{pyxb.binding.content.ElementDeclaration} that is the preferred
     360          symbol for the transition.
     361
     362          @return: the cardinal number of successful transitions from the
     363          current configuration based on the parameters."""
     364
     365          sym = (value, element_decl)
     366
     367          # Start with the current configuration(s), assuming we might see
     368          # non-determinism.
     369          new_multi = []
     370          if self.__multi is None:
     371              multi = [ (self.__cfg, ()) ]
     372          else:
     373              multi = self.__multi[:]
     374          # Collect the complete set of reachable configurations along with the
     375          # closures that will update the instance content based on the path.
     376          for (cfg, pending) in multi:
     377              cand = cfg.candidateTransitions(sym)
     378              for transition in cand:
     379                  clone_map = {}
     380                  ccfg = cfg.clone(clone_map)
     381                  new_multi.append( (transition.apply(ccfg, clone_map), pending+(transition.consumedSymbol().consumingClosure(sym),)) )
     382          rv = len(new_multi)
     383          if 0 == rv:
     384              # No candidate transitions.  Do not change the state.
     385              return 0
     386          if 1 == rv:
     387              # Deterministic transition.  Save the configuration and apply the
     388              # corresponding updates.
     389              self.__multi = None
     390              (self.__cfg, actions) = new_multi[0]
     391              for fn in actions:
     392                  fn(self.__instance)
     393          else:
     394              # Non-deterministic.  Save everything for subsequent resolution.
     395              self.__cfg = None
     396              self.__multi = new_multi
     397          return rv
     398
     399 -    def resolveNondeterminism (self, prefer_accepting=True):
     400          """Resolve any non-determinism in the automaton state.
     401
     402          If the automaton has reached a single configuration (was
     403          deterministic), this does nothing.
     404
     405          If multiple candidate configurations are available, the best one is
     406          selected and applied, updating the binding instance with the pending
     407          content.
     408
     409          "Best" in this case is determined by optionally eliminating
     410          configurations that are not accepting, then selecting the path where
     411          the initial transition sorts highest using the binding sort key (based
     412          on position in the original schema).
     413
     414          @keyword prefer_accepting: eliminate non-accepting paths if any
     415          accepting path is present."""
     416          if self.__multi is None:
     417              return
     418          assert self.__cfg is None
     419          multi = self.__multi
     420          if prefer_accepting:
     421              multi = filter(lambda _ts: _ts[0].isAccepting(), self.__multi)
     422              if 0 == len(multi):
     423                  multi = self.__multi
     424          # step() will not create an empty multi list, so cannot get here with
     425          # no configurations available unless nobody even reset the
     426          # configuration, which would be a usage error.
     427          assert 0 < len(multi)
     428          if 1 < len(multi):
     429              desc = self.__instance._ExpandedName
     430              if desc is None:
     431                  desc = type(self.__instance)
     432              _log.warning('Multiple accepting paths for %s', desc)
     433              '''
     434              for (cfg, actions) in multi:
     435                  foo = type(self.__instance)()
     436                  for fn in actions:
     437                      fn(foo)
     438                  print '1: %s ; 2 : %s ; wc: %s' % (foo.first, foo.second, foo.wildcardElements())
     439              '''
     440          (self.__cfg, actions) = multi[0]
     441          self.__multi = None
     442          for fn in actions:
     443              fn(self.__instance)
     444
     445 -    def acceptableContent (self):
     446          """Return the sequence of acceptable symbols at this state.
     447
     448          The list comprises the L{pyxb.binding.content.ElementUse} and
     449          L{pyxb.binding.content.WildcardUse} instances that are used to
     450          validate proposed symbols, in preferred order."""
     451          rv = []
     452          seen = set()
     453          multi = self.__multi
     454          if multi is None:
     455              multi = [ self.__cfg]
     456          for cfg in multi:
     457              for u in cfg.acceptableSymbols():
     458                  if not (u in seen):
     459                      rv.append(u)
     460                      seen.add(u)
     461          return rv
     462
     463 -    def isAccepting (self, raise_if_rejecting=False):
     464          """Return C{True} iff the automaton is in an accepting state.
     465
     466          If the automaton has unresolved nondeterminism, it is resolved first,
     467          preferring accepting states."""
     468          self.resolveNondeterminism(True)
     469          cfg = self.__cfg
     470          while cfg.superConfiguration is not None:
     471              cfg = cfg.superConfiguration
     472          return cfg.isAccepting()
     473
     474 -    def _diagnoseIncompleteContent (self, symbols, symbol_set):
     475          """Check for incomplete content.
     476
     477          @raises pyxb.IncompleteElementContentError: if a non-accepting state is found
     478          @return: the topmost configuration (if accepting)
     479          """
     480          # Exit out of any sub-configurations (they might be accepting while
     481          # the superConfiguration is not)
     482          cfg = self.__cfg
     483          while cfg.isAccepting() and (cfg.superConfiguration is not None):
     484              cfg = cfg.superConfiguration
     485          if not cfg.isAccepting():
     486              _log.warning('Incomplete content, expect %s' % (' or '.join(map(str, cfg.acceptableSymbols()))))
     487              raise pyxb.IncompleteElementContentError(self.__instance, cfg, symbols, symbol_set)
     488          return cfg
     489
     490 -    def diagnoseIncompleteContent (self):
     491          """Generate the exception explaining why the content is incomplete."""
     492          return self._diagnoseIncompleteContent(None, None)
     493
     494      __preferredSequenceIndex = 0
     495      __preferredPendingSymbol = None
     496      __pendingNonElementContent = None
     497
     498 -    def __resetPreferredSequence (self, instance):
     499          self.__preferredSequenceIndex = 0
     500          self.__preferredPendingSymbol = None
     501          self.__pendingNonElementContent = None
     502          vc = instance._validationConfig
     503          preferred_sequence = None
     504          if (vc.ALWAYS == vc.contentInfluencesGeneration) or (instance._ContentTypeTag == instance._CT_MIXED and vc.MIXED_ONLY == vc.contentInfluencesGeneration):
     505              preferred_sequence = instance.orderedContent()
     506              if instance._ContentTypeTag == instance._CT_MIXED:
     507                  self.__pendingNonElementContent = []
     508          return preferred_sequence
     509
     510 -    def __discardPreferredSequence (self, preferred_sequence, pi=None):
     511          """Extract non-element content from the sequence and return C{None}."""
     512          if pi is None:
     513              pi = self.__preferredSequenceIndex
     514          nec = self.__pendingNonElementContent
     515          if nec is not None:
     516              for csym in preferred_sequence[pi:]:
     517                  if isinstance(csym, pyxb.binding.basis.NonElementContent):
     518                      nec.append(csym)
     519          return None
     520
     521 -    def __processPreferredSequence (self, preferred_sequence, symbol_set, vc):
     522          pi = self.__preferredSequenceIndex
     523          psym = self.__preferredPendingSymbol
     524          nec = self.__pendingNonElementContent
     525          if psym is not None:
     526              _log.info('restoring %s', psym)
     527              self.__preferredPendingSymbol = None
     528          while psym is None:
     529              if pi >= len(preferred_sequence):
     530                  preferred_sequence = self.__discardPreferredSequence(preferred_sequence, pi)
     531                  break
     532              csym = preferred_sequence[pi]
     533              pi += 1
     534              if (nec is not None) and isinstance(csym, pyxb.binding.basis.NonElementContent):
     535                  nec.append(csym)
     536                  continue
     537              vals = symbol_set.get(csym.elementDeclaration, [])
     538              if csym.value in vals:
     539                  psym = ( csym.value, csym.elementDeclaration )
     540                  break
     541              if psym is None:
     542                  # Orphan encountered; response?
     543                  _log.info('orphan %s in content', csym)
     544                  if vc.IGNORE_ONCE == vc.orphanElementInContent:
     545                      continue
     546                  if vc.GIVE_UP == vc.orphanElementInContent:
     547                      preferred_sequence = self.__discardPreferredSequence(preferred_sequence, pi)
     548                      break
     549                  raise pyxb.OrphanElementContentError(self.__instance, csym)
     550          self.__preferredSequenceIndex = pi
     551          return (preferred_sequence, psym)
     552
     553 -    def sequencedChildren (self):
     554          """Implement L{pyxb.binding.basis.complexTypeDefinition._validatedChildren}.
     555
     556          Go there for the interface.
     557          """
     558
     559          # We need a fresh automaton configuration corresponding to the type of
     560          # the binding instance.
     561          self.reset()
     562          cfg = self.__cfg
     563
     564          # The validated sequence
     565          symbols = []
     566
     567          # How validation should be done
     568          instance = self.__instance
     569          vc = instance._validationConfig
     570
     571          # The available content, in a map from ElementDeclaration to in-order
     572          # values.  The key None corresponds to the wildcard content.  Keys are
     573          # removed when their corresponding content is exhausted.
     574          symbol_set = instance._symbolSet()
     575
     576          # The preferred sequence to use, if desired.
     577          preferred_sequence = self.__resetPreferredSequence(instance)
     578
     579          # A reference to the data structure holding non-element content.  This
     580          # is None unless mixed content is allowed, in which case it is a list.
     581          # The same list is used for the entire operation, though it is reset
     582          # to be empty after transferring material to the output sequence.
     583          nec = self.__pendingNonElementContent
     584
     585          psym = None
     586          while symbol_set:
     587              # Find the first acceptable transition.  If there's a preferred
     588              # symbol to use, try it first.
     589              selected_xit = None
     590              psym = None
     591              if preferred_sequence is not None:
     592                  (preferred_sequence, psym) = self.__processPreferredSequence(preferred_sequence, symbol_set, vc)
     593              candidates = cfg.candidateTransitions(psym)
     594              for xit in candidates:
     595                  csym = xit.consumedSymbol()
     596                  if isinstance(csym, ElementUse):
     597                      ed = csym.elementDeclaration()
     598                  elif isinstance(csym, WildcardUse):
     599                      ed = None
     600                  else:
     601                      assert False
     602                  # Check whether we have content that matches the symbol
     603                  matches = symbol_set.get(ed)
     604                  if matches is None:
     605                      continue
     606                  if not csym.match((matches[0], ed)):
     607                      continue
     608                  # Commit to this transition and append the selected content
     609                  # after any pending non-element content that is released due
     610                  # to a matched preferred symbol.
     611                  value = matches.pop(0)
     612                  if (psym is not None) and (nec is not None):
     613                      symbols.extend(nec)
     614                      nec[:] = []
     615                  symbols.append(basis.ElementContent(csym.matchValue( (value, ed) ), ed))
     616                  selected_xit = xit
     617                  if 0 == len(matches):
     618                      del symbol_set[ed]
     619                  break
     620              if selected_xit is None:
     621                  if psym is not None:
     622                      # Suggestion from content did not work
     623                      _log.info('invalid %s in content', psym)
     624                      if vc.IGNORE_ONCE == vc.invalidElementInContent:
     625                          continue
     626                      if vc.GIVE_UP == vc.invalidElementInContent:
     627                          preferred_sequence = self.__discardPreferredSequence(preferred_sequence)
     628                          continue
     629                      raise pyxb.InvalidPreferredElementContentError(self.__instance, cfg, symbols, symbol_set, psym)
     630                  break
     631              cfg = selected_xit.apply(cfg)
     632          cfg = self._diagnoseIncompleteContent(symbols, symbol_set)
     633          if symbol_set:
     634              raise pyxb.UnprocessedElementContentError(self.__instance, cfg, symbols, symbol_set)
     635          # Validate any remaining material in the preferred sequence.  This
     636          # also extracts remaining non-element content.  Note there are
     637          # no more symbols, so any remaining element content is orphan.
     638          while preferred_sequence is not None:
     639              (preferred_sequence, psym) = self.__processPreferredSequence(preferred_sequence, symbol_set, vc)
     640              if psym is not None:
     641                  if not (vc.orphanElementInContent in ( vc.IGNORE_ONCE, vc.GIVE_UP )):
     642                      raise pyxb.OrphanElementContentError(self.__instance, psym.value)
     643          if nec is not None:
     644              symbols.extend(nec)
     645          return symbols
     646
     647 -class _FACSymbol (pyxb.utils.fac.SymbolMatch_mixin):
     648      """Base class for L{pyxb.utils.fac.Symbol} instances associated with PyXB content models.
     649
     650      This holds the location in the schema of the L{ElementUse} or
     651      L{WildcardUse} and documents the methods expected of its children."""
     652
     653      __xsdLocation = None
     654
     655 -    def xsdLocation (self):
     656          return self.__xsdLocation
     657
     658 -    def matchValue (self, sym):
     659          """Return the value accepted by L{match} for this symbol.
     660
     661          A match for an element declaration might have resulted in a type
     662          change for the value (converting it to an acceptable type).  There is
     663          no safe place to cache the compatible value calculated in the match
     664          while other candidates are being considered, so we need to
     665          re-calculate it if the transition is taken.
     666
     667          If the match could not have changed the value, the value from the
     668          symbol may be returned immediately."""
     669          raise NotImplementedError('%s._matchValue' % (type(self).__name__,))
     670
     671 -    def consumingClosure (self, sym):
     672          """Create a closure that will apply the value from C{sym} to a to-be-supplied instance.
     673
     674          This is necessary for non-deterministic automata, where we can't store
     675          the value into the instance field until we know that the transition
     676          will be taken:
     677
     678          @return: A closure that takes a L{complexTypeDefinition} instance and
     679          stores the value from invoking L{matchValue} on C{sym} into the
     680          appropriate slot."""
     681          raise NotImplementedError('%s._consumingClosure' % (type(self).__name__,))
     682
     683 -    def __init__ (self, xsd_location):
     684          """@param xsd_location: the L{location<pyxb.utils.utility.Location>} of the element use or wildcard declaration."""
     685          self.__xsdLocation = xsd_location
     686          super(_FACSymbol, self).__init__()
     687
     688 -class ElementUse (_FACSymbol):
     689      """Information about a schema element declaration reference.
     690
     691      This is used by the FAC content model to identify the location
     692      within a schema at which an element use appears.  The L{ElementDeclaration}
     693      is not sufficient since multiple uses in various schema, possibly in
     694      different namespaces, may refer to the same declaration but be independent
     695      uses.
     696      """
     697
     698      __elementDeclaration = None
     699
     700 -    def elementDeclaration (self):
     701          """Return the L{element declaration<pyxb.binding.content.ElementDeclaration>} associated with the use."""
     702          return self.__elementDeclaration
     703
     704 -    def elementBinding (self):
     705          """Return the L{element binding<pyxb.binding.content.ElementDeclaration.elementBinding>} associated with the use.
     706
     707          Equivalent to L{elementDeclaration}().L{elementBinding()<pyxb.binding.content.ElementDeclaration.elementBinding>}."""
     708          return self.__elementDeclaration.elementBinding()
     709
     710 -    def typeDefinition (self):
     711          """Return the element type.
     712
     713          Equivalent to L{elementDeclaration}().L{elementBinding()<pyxb.binding.content.ElementDeclaration.elementBinding>}.L{typeDefinition()<pyxb.binding.basis.element.typeDefinition>}."""
     714          return self.__elementDeclaration.elementBinding().typeDefinition()
     715
     716 -    def __init__ (self, element_declaration, xsd_location):
     717          super(ElementUse, self).__init__(xsd_location)
     718          self.__elementDeclaration = element_declaration
     719
     720 -    def matchValue (self, sym):
     721          (value, element_decl) = sym
     722          (rv, value) = self.__elementDeclaration._matches(value, element_decl)
     723          assert rv
     724          return value
     725
     726 -    def consumingClosure (self, sym):
     727          # Defer the potentially-expensive re-invocation of matchValue until
     728          # the closure is applied.
     729          return lambda _inst,_eu=self,_sy=sym: _eu.__elementDeclaration.setOrAppend(_inst, _eu.matchValue(_sy))
     730
     731 -    def match (self, symbol):
     732          """Satisfy L{pyxb.utils.fac.SymbolMatch_mixin}.
     733
     734          Determine whether the proposed content encapsulated in C{symbol} is
     735          compatible with the element declaration.  If so, the accepted value is
     736          cached internally and return C{True}; otherwise return C{False}.
     737
     738          @param symbol: a pair C{(value, element_decl)}.
     739          L{pyxb.binding.content.ElementDeclaration._matches} is used to
     740          determine whether the proposed content is compatible with this element
     741          declaration."""
     742          (value, element_decl) = symbol
     743          # NB: this call may change value to be compatible.  Unfortunately, we
     744          # can't reliably cache that converted value, so just ignore it and
     745          # we'll recompute it if the candidate transition is taken.
     746          (rv, value) = self.__elementDeclaration._matches(value, element_decl)
     747          return rv
     748
     749 -    def __str__ (self):
     750          return '%s per %s' % (self.__elementDeclaration.name(), self.xsdLocation())
     751
     752 -class WildcardUse (_FACSymbol):
     753      """Information about a schema wildcard element.
     754
     755      This is functionally parallel to L{ElementUse}, but references a
     756      L{Wildcard} that is unique to this instance.  That L{Wildcard} is not
     757      incorporated into this class is an artifact of the evolution of PyXB."""
     758
     759      __wildcardDeclaration = None
     760
     761 -    def wildcardDeclaration (self):
     762          return self.__wildcardDeclaration
     763
     764 -    def matchValue (self, sym):
     765          (value, element_decl) = sym
     766          return value
     767
     768 -    def consumingClosure (self, sym):
     769          """Create a closure that will apply the value accepted by L{match} to a to-be-supplied instance."""
     770          return lambda _inst,_av=self.matchValue(sym): _inst._appendWildcardElement(_av)
     771
     772 -    def match (self, symbol):
     773          """Satisfy L{pyxb.utils.fac.SymbolMatch_mixin}.
     774
     775          Determine whether the proposed content encapsulated in C{symbol} is
     776          compatible with the wildcard declaration.  If so, the accepted value
     777          is cached internally and return C{True}; otherwise return C{False}.
     778
     779          @param symbol: a pair C{(value, element_decl)}.
     780          L{pyxb.binding.content.Wildcard.matches} is used to determine whether
     781          the proposed content is compatible with this wildcard.
     782          """
     783          (value, element_decl) = symbol
     784          return self.__wildcardDeclaration.matches(None, value)
     785
     786 -    def __init__ (self, wildcard_declaration, xsd_location):
     787          super(WildcardUse, self).__init__(xsd_location)
     788          self.__wildcardDeclaration = wildcard_declaration
     789
     790 -    def __str__ (self):
     791          return 'xs:any per %s' % (self.xsdLocation(),)
     792
     793  import collections
     794
     795  # Do not inherit from list; that's obscene, and could cause problems with the
     796  # internal assumptions made by Python.  Instead delegate everything to an
     797  # instance of list that's held internally.  Inherit from the ABC that
     798  # represents list-style data structures so we can identify both lists and
     799  # these things which are not lists.
     800  @pyxb.utils.utility.BackfillComparisons
     801 -class _PluralBinding (collections.MutableSequence):
     802      """Helper for element content that supports multiple occurences.
     803
     804      This is an adapter for Python list.  Any operation that can mutate an item
     805      in the list ensures the stored value is compatible with the element for
     806      which the list holds values."""
     807
     808      __list = None
     809      __elementBinding = None
     810
     811 -    def __init__ (self, *args, **kw):
     812          element_binding = kw.pop('element_binding', None)
     813          if not isinstance(element_binding, basis.element):
     814              raise ValueError()
     815          self.__elementBinding = element_binding
     816          self.__list = []
     817          self.extend(args)
     818
     819 -    def __convert (self, v):
     820          return self.__elementBinding.compatibleValue(v)
     821
     822 -    def __len__ (self):
     823          return self.__list.__len__()
     824
     825 -    def __getitem__ (self, key):
     826          return self.__list.__getitem__(key)
     827
     828 -    def __setitem__ (self, key, value):
     829          if isinstance(key, slice):
     830              self.__list.__setitem__(key, [ self.__convert(_v) for _v in value])
     831          else:
     832              self.__list.__setitem__(key, self.__convert(value))
     833
     834 -    def __delitem__ (self, key):
     835          self.__list.__delitem__(key)
     836
     837 -    def __iter__ (self):
     838          return self.__list.__iter__()
     839
     840 -    def __reversed__ (self):
     841          return self.__list.__reversed__()
     842
     843 -    def __contains__ (self, item):
     844          return self.__list.__contains__(item)
     845
     846      # The mutable sequence type methods
     847 -    def append (self, x):
     848          self.__list.append(self.__convert(x))
     849
     850 -    def extend (self, x):
     851          self.__list.extend(map(self.__convert, x))
     852
     853 -    def count (self, x):
     854          return self.__list.count(x)
     855
     856 -    def index (self, x, i=0, j=-1):
     857          return self.__list.index(x, i, j)
     858
     859 -    def insert (self, i, x):
     860          self.__list.insert(i, self.__convert(x))
     861
     862 -    def pop (self, i=-1):
     863          return self.__list.pop(i)
     864
     865 -    def remove (self, x):
     866          self.__list.remove(x)
     867
     868 -    def reverse (self):
     869          self.__list.reverse()
     870
     871 -    def sort (self, key=None, reverse=False):
     872          self.__list.sort(key=key, reverse=reverse)
     873
     874 -    def __str__ (self):
     875          return self.__list.__str__()
     876
     877 -    def __hash__ (self):
     878          return hash(self.__list__)
     879
     880 -    def __eq__ (self, other):
     881          if isinstance(other, _PluralBinding):
     882              return self.__list.__eq__(other.__list)
     883          return self.__list.__eq__(other)
     884
     885 -    def __le__ (self, other):
     886          if isinstance(other, _PluralBinding):
     887              return self.__list.__le__(other.__list)
     888          return self.__list.__le__(other)
     889
     890 -class ElementDeclaration (object):
     891      """Aggregate the information relevant to an element of a complex type.
     892
     893      This includes the L{original tag name<name>}, the spelling of L{the
     894      corresponding object in Python <id>}, an L{indicator<isPlural>} of whether
     895      multiple instances might be associated with the field, and other relevant
     896      information.
     897      """
     898
     899 -    def xsdLocation (self):
     900          """The L{location<pyxb.utils.utility.Location>} in the schema where the
     901          element was declared.
     902
     903          Note that this is not necessarily the same location as its use."""
     904          return self.__xsdLocation
     905      __xsdLocation = None
     906
     907 -    def name (self):
     908          """The expanded name of the element.
     909
     910          @rtype: L{pyxb.namespace.ExpandedName}
     911          """
     912          return self.__name
     913      __name = None
     914
     915 -    def id (self):
     916          """The string name of the binding class field used to hold the element
     917          values.
     918
     919          This is the user-visible name, and excepting disambiguation will be
     920          equal to the local name of the element."""
     921          return self.__id
     922      __id = None
     923
     924      # The dictionary key used to identify the value of the element.  The value
     925      # is the same as that used for private member variables in the binding
     926      # class within which the element declaration occurred.
     927      __key = None
     928
     929 -    def elementBinding (self):
     930          """The L{basis.element} instance identifying the information
     931          associated with the element declaration.
     932          """
     933          return self.__elementBinding
     934 -    def _setElementBinding (self, element_binding):
     935          # Set the element binding for this use.  Only visible at all because
     936          # we have to define the uses before the element instances have been
     937          # created.
     938          self.__elementBinding = element_binding
     939          return self
     940      __elementBinding = None
     941
     942 -    def isPlural (self):
     943          """True iff the content model indicates that more than one element
     944          can legitimately belong to this use.
     945
     946          This includes elements in particles with maxOccurs greater than one,
     947          and when multiple elements with the same NCName are declared in the
     948          same type.
     949          """
     950          return self.__isPlural
     951      __isPlural = False
     952
     953 -    def __init__ (self, name, id, key, is_plural, location, element_binding=None):
     954          """Create an ElementDeclaration instance.
     955
     956          @param name: The name by which the element is referenced in the XML
     957          @type name: L{pyxb.namespace.ExpandedName}
     958
     959          @param id: The Python name for the element within the containing
     960          L{pyxb.basis.binding.complexTypeDefinition}.  This is a public
     961          identifier, albeit modified to be unique, and is usually used as the
     962          name of the element's inspector method or property.
     963          @type id: C{str}
     964
     965          @param key: The string used to store the element
     966          value in the dictionary of the containing
     967          L{pyxb.basis.binding.complexTypeDefinition}.  This is mangled so
     968          that it is unique among and is treated as a Python private member.
     969          @type key: C{str}
     970
     971          @param is_plural: If C{True}, documents for the corresponding type may
     972          have multiple instances of this element.  As a consequence, the value
     973          of the element will be a list.  If C{False}, the value will be C{None}
     974          if the element is absent, and a reference to an instance of the type
     975          identified by L{pyxb.binding.basis.element.typeDefinition} if present.
     976          @type is_plural: C{bool}
     977
     978          @param element_binding: Reference to the class that serves as the
     979          binding for the element.
     980          """
     981          self.__name = name
     982          self.__id = id
     983          self.__key = key
     984          self.__isPlural = is_plural
     985          self.__elementBinding = element_binding
     986          super(ElementDeclaration, self).__init__()
     987
     988 -    def defaultValue (self):
     989          """Return the default value for this element.
     990
     991          For plural values, this is an empty collection.  For non-plural
     992          values, it is C{None} unless the element has a default value, in which
     993          case it is that value.
     994
     995          @todo: This should recursively support filling in default content, as
     996          when the plural list requires a non-zero minimum number of entries.
     997          """
     998          if self.isPlural():
     999              return _PluralBinding(element_binding=self.__elementBinding)
    1000          return self.__elementBinding.defaultValue()
    1001
    1002 -    def resetValue (self):
    1003          """Return the reset value for this element.
    1004
    1005          For plural values, this is an empty collection.  For non-plural
    1006          values, it is C{None}, corresponding to absence of an assigned
    1007          element.
    1008          """
    1009          if self.isPlural():
    1010              return _PluralBinding(element_binding=self.__elementBinding)
    1011          return None
    1012
    1013 -    def value (self, ctd_instance):
    1014          """Return the value for this use within the given instance.
    1015
    1016          Note that this is the L{resetValue()}, not the L{defaultValue()}, if
    1017          the element has not yet been assigned a value."""
    1018          return getattr(ctd_instance, self.__key, self.resetValue())
    1019
    1020 -    def reset (self, ctd_instance):
    1021          """Set the value for this use in the given element to its default."""
    1022          setattr(ctd_instance, self.__key, self.resetValue())
    1023          return self
    1024
    1025 -    def set (self, ctd_instance, value):
    1026          """Set the value of this element in the given instance."""
    1027          if value is None:
    1028              return self.reset(ctd_instance)
    1029          if ctd_instance._isNil():
    1030              raise pyxb.ContentInNilInstanceError(ctd_instance, value)
    1031          assert self.__elementBinding is not None
    1032          if ctd_instance._validationConfig.forBinding or isinstance(value, pyxb.BIND):
    1033              value = self.__elementBinding.compatibleValue(value, is_plural=self.isPlural())
    1034          setattr(ctd_instance, self.__key, value)
    1035          ctd_instance._addContent(basis.ElementContent(value, self))
    1036          return self
    1037
    1038 -    def setOrAppend (self, ctd_instance, value):
    1039          """Invoke either L{set} or L{append}, depending on whether the element
    1040          use is plural."""
    1041          if self.isPlural():
    1042              return self.append(ctd_instance, value)
    1043          return self.set(ctd_instance, value)
    1044
    1045 -    def append (self, ctd_instance, value):
    1046          """Add the given value as another instance of this element within the binding instance.
    1047          @raise pyxb.StructuralBadDocumentError: invoked on an element use that is not plural
    1048          """
    1049          if ctd_instance._isNil():
    1050              raise pyxb.ContentInNilInstanceError(ctd_instance, value)
    1051          if not self.isPlural():
    1052              raise pyxb.NonPluralAppendError(ctd_instance, self, value)
    1053          values = self.value(ctd_instance)
    1054          if ctd_instance._validationConfig.forBinding:
    1055              value = self.__elementBinding.compatibleValue(value)
    1056          values.append(value)
    1057          ctd_instance._addContent(basis.ElementContent(value, self))
    1058          return values
    1059
    1060 -    def toDOM (self, dom_support, parent, value):
    1061          """Convert the given value to DOM as an instance of this element.
    1062
    1063          @param dom_support: Helper for managing DOM properties
    1064          @type dom_support: L{pyxb.utils.domutils.BindingDOMSupport}
    1065          @param parent: The DOM node within which this element should be generated.
    1066          @type parent: C{xml.dom.Element}
    1067          @param value: The content for this element.  May be text (if the
    1068          element allows mixed content), or an instance of
    1069          L{basis._TypeBinding_mixin}.
    1070
    1071          @raise pyxb.AbstractElementError: the binding to be used is abstract
    1072          """
    1073          if isinstance(value, basis._TypeBinding_mixin):
    1074              element_binding = self.__elementBinding
    1075              if value._substitutesFor(element_binding):
    1076                  element_binding = value._element()
    1077              assert element_binding is not None
    1078              if element_binding.abstract():
    1079                  raise pyxb.AbstractElementError(self, value)
    1080              element = dom_support.createChildElement(element_binding.name(), parent)
    1081              elt_type = element_binding.typeDefinition()
    1082              val_type = type(value)
    1083              if isinstance(value, basis.complexTypeDefinition):
    1084                  assert isinstance(value, elt_type)
    1085              else:
    1086                  if isinstance(value, basis.STD_union) and isinstance(value, elt_type._MemberTypes):
    1087                      val_type = elt_type
    1088              if dom_support.requireXSIType() or elt_type._RequireXSIType(val_type):
    1089                  val_type_qname = value._ExpandedName.localName()
    1090                  tns_prefix = dom_support.namespacePrefix(value._ExpandedName.namespace())
    1091                  if tns_prefix is not None:
    1092                      val_type_qname = '%s:%s' % (tns_prefix, val_type_qname)
    1093                  dom_support.addAttribute(element, pyxb.namespace.XMLSchema_instance.createExpandedName('type'), val_type_qname)
    1094              value._toDOM_csc(dom_support, element)
    1095          elif isinstance(value, (str, unicode)):
    1096              element = dom_support.createChildElement(self.name(), parent)
    1097              element.appendChild(dom_support.document().createTextNode(value))
    1098          else:
    1099              raise pyxb.LogicError('toDOM with unrecognized value type %s: %s' % (type(value), value))
    1100
    1101 -    def _description (self, name_only=False, user_documentation=True):
    1102          if name_only:
    1103              return unicode(self.__name)
    1104          desc = [ unicode(self.__id), ': ']
    1105          if self.isPlural():
    1106              desc.append('MULTIPLE ')
    1107          desc.append(self.elementBinding()._description(user_documentation=user_documentation))
    1108          return u''.join(desc)
    1109
    1110 -    def _matches (self, value, element_decl):
    1111          accept = False
    1112          if element_decl == self:
    1113              accept = True
    1114          elif element_decl is not None:
    1115              # If there's a known element, and it's not this one, the content
    1116              # does not match.  This assumes we handled xsi:type and
    1117              # substitution groups earlier, which may be true.
    1118              accept = False
    1119          elif isinstance(value, xml.dom.Node):
    1120              # If we haven't been able to identify an element for this before,
    1121              # then we don't recognize it, and will have to treat it as a
    1122              # wildcard.
    1123              accept = False
    1124          else:
    1125              # A foreign value which might be usable if we can convert
    1126              # it to a compatible value trivially.
    1127              try:
    1128                  value = self.__elementBinding.compatibleValue(value, _convert_string_values=False)
    1129                  accept = True
    1130              except (pyxb.ValidationError, pyxb.BindingError):
    1131                  pass
    1132          return (accept, value)
    1133
    1134 -    def __str__ (self):
    1135          return 'ED.%s@%x' % (self.__name, id(self))
    1136
    1137
    1138 -class Wildcard (object):
    1139      """Placeholder for wildcard objects."""
    1140
    1141      NC_any = '##any'            #<<< The namespace constraint "##any"
    1142      NC_not = '##other'          #<<< A flag indicating constraint "##other"
    1143      NC_targetNamespace = '##targetNamespace' #<<< A flag identifying the target namespace
    1144      NC_local = '##local'        #<<< A flag indicating the namespace must be absent
    1145
    1146      __namespaceConstraint = None
    1147 -    def namespaceConstraint (self):
    1148          """A constraint on the namespace for the wildcard.
    1149
    1150          Valid values are:
    1151
    1152           - L{Wildcard.NC_any}
    1153           - A tuple ( L{Wildcard.NC_not}, a L{namespace<pyxb.namespace.Namespace>} instance )
    1154           - set(of L{namespace<pyxb.namespace.Namespace>} instances)
    1155
    1156          Namespaces are represented by their URIs.  Absence is
    1157          represented by C{None}, both in the "not" pair and in the set.
    1158          """
    1159          return self.__namespaceConstraint
    1160
    1161      PC_skip = 'skip'
    1162      """No namespace constraint is applied to the wildcard."""
    1163
    1164      PC_lax = 'lax'
    1165      """Validate against available uniquely determined declaration."""
    1166
    1167      PC_strict = 'strict'
    1168      """Validate against declaration or xsi:type, which must be available."""
    1169
    1170      __processContents = None
    1171      """One of L{PC_skip}, L{PC_lax}, L{PC_strict}."""
    1172 -    def processContents (self):
    1173          """Indicate how this wildcard's contents should be processed."""
    1174          return self.__processContents
    1175
    1176 -    def __normalizeNamespace (self, nsv):
    1177          if nsv is None:
    1178              return None
    1179          if isinstance(nsv, basestring):
    1180              nsv = pyxb.namespace.NamespaceForURI(nsv, create_if_missing=True)
    1181          assert isinstance(nsv, pyxb.namespace.Namespace), 'unexpected non-namespace %s' % (nsv,)
    1182          return nsv
    1183
    1184 -    def __init__ (self, *args, **kw):
    1185          """
    1186          @keyword namespace_constraint: Required namespace constraint(s)
    1187          @keyword process_contents: Required"""
    1188
    1189          # Namespace constraint and process contents are required parameters.
    1190          nsc = kw['namespace_constraint']
    1191          if isinstance(nsc, tuple):
    1192              nsc = (nsc[0], self.__normalizeNamespace(nsc[1]))
    1193          elif isinstance(nsc, set):
    1194              nsc = set([ self.__normalizeNamespace(_uri) for _uri in nsc ])
    1195          self.__namespaceConstraint = nsc
    1196          self.__processContents = kw['process_contents']
    1197          super(Wildcard, self).__init__()
    1198
    1199 -    def matches (self, instance, value):
    1200          """Return True iff the value is a valid match against this wildcard.
    1201
    1202          Validation per U{Wildcard allows Namespace Name<http://www.w3.org/TR/xmlschema-1/#cvc-wildcard-namespace>}.
    1203          """
    1204
    1205          ns = None
    1206          if isinstance(value, xml.dom.Node):
    1207              if value.namespaceURI is not None:
    1208                  ns = pyxb.namespace.NamespaceForURI(value.namespaceURI)
    1209          elif isinstance(value, basis._TypeBinding_mixin):
    1210              elt = value._element()
    1211              if elt is not None:
    1212                  ns = elt.name().namespace()
    1213              else:
    1214                  ns = value._ExpandedName.namespace()
    1215          else:
    1216              # Assume that somebody will handle the conversion to xs:anyType
    1217              pass
    1218          if isinstance(ns, pyxb.namespace.Namespace) and ns.isAbsentNamespace():
    1219              ns = None
    1220          if self.NC_any == self.__namespaceConstraint:
    1221              return True
    1222          if isinstance(self.__namespaceConstraint, tuple):
    1223              (_, constrained_ns) = self.__namespaceConstraint
    1224              assert self.NC_not == _
    1225              if ns is None:
    1226                  return False
    1227              if constrained_ns == ns:
    1228                  return False
    1229              return True
    1230          return ns in self.__namespaceConstraint
    1231
    1232  ## Local Variables:
    1233  ## fill-column:78
    1234  ## End:
    1235