Package pyxb :: Package namespace :: Module resolution
[hide private]
[frames] | no frames]

Source Code for Module pyxb.namespace.resolution

  1  # -*- coding: utf-8 -*- 
  2  # Copyright 2009-2012, Peter A. Bigot 
  3  # 
  4  # Licensed under the Apache License, Version 2.0 (the "License"); you may 
  5  # not use this file except in compliance with the License. You may obtain a 
  6  # copy of the License at: 
  7  # 
  8  #            http://www.apache.org/licenses/LICENSE-2.0 
  9  # 
 10  # Unless required by applicable law or agreed to in writing, software 
 11  # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
 12  # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
 13  # License for the specific language governing permissions and limitations 
 14  # under the License. 
 15   
 16  """Classes and global objects related to resolving U{XML 
 17  Namespaces<http://www.w3.org/TR/2006/REC-xml-names-20060816/index.html>}.""" 
 18   
 19  import pyxb 
 20  import pyxb.utils.utility 
 21  from pyxb.namespace import archive, utility 
 22  import logging 
 23   
 24  _log = logging.getLogger(__name__) 
25 26 -class _Resolvable_mixin (pyxb.cscRoot):
27 """Mix-in indicating that this object may have references to unseen named components. 28 29 This class is mixed-in to those XMLSchema components that have a reference 30 to another component that is identified by a QName. Resolution of that 31 component may need to be delayed if the definition of the component has 32 not yet been read. 33 """ 34 35 #_TraceResolution = True 36 _TraceResolution = False 37
38 - def isResolved (self):
39 """Determine whether this named component is resolved. 40 41 Override this in the child class.""" 42 raise pyxb.LogicError('Resolved check not implemented in %s' % (self.__class__,))
43
44 - def _resolve (self):
45 """Perform whatever steps are required to resolve this component. 46 47 Resolution is performed in the context of the namespace to which the 48 component belongs. Invoking this method may fail to complete the 49 resolution process if the component itself depends on unresolved 50 components. The sole caller of this should be 51 L{_NamespaceResolution_mixin.resolveDefinitions}. 52 53 This method is permitted (nay, encouraged) to raise an exception if 54 resolution requires interpreting a QName and the named component 55 cannot be found. 56 57 Override this in the child class. In the prefix, if L{isResolved} is 58 true, return right away. If something prevents you from completing 59 resolution, invoke L{self._queueForResolution()} (so it is retried 60 later) and immediately return self. Prior to leaving after successful 61 resolution discard any cached dom node by setting C{self.__domNode=None}. 62 63 @return: C{self}, whether or not resolution succeeds. 64 @raise pyxb.SchemaValidationError: if resolution requlres a reference to an unknown component 65 """ 66 raise pyxb.LogicError('Resolution not implemented in %s' % (self.__class__,))
67
68 - def _queueForResolution (self, why=None, depends_on=None):
69 """Short-hand to requeue an object if the class implements _namespaceContext(). 70 """ 71 if (why is not None) and self._TraceResolution: 72 _log.info('Resolution delayed for %s: %s\n\tDepends on: %s', self, why, depends_on) 73 self._namespaceContext().queueForResolution(self, depends_on)
74
75 -class _NamespaceResolution_mixin (pyxb.cscRoot):
76 """Mix-in that aggregates those aspects of XMLNamespaces relevant to 77 resolving component references. 78 """ 79 80 # A set of namespaces which some schema imported while processing with 81 # this namespace as target. 82 __importedNamespaces = None 83 84 # A set of namespaces which appear in namespace declarations of schema 85 # with this namespace as target. 86 __referencedNamespaces = None 87 88 # A list of Namespace._Resolvable_mixin instances that have yet to be 89 # resolved. 90 __unresolvedComponents = None 91 92 # A map from Namespace._Resolvable_mixin instances in 93 # __unresolvedComponents to sets of other unresolved objects on which they 94 # depend. 95 __unresolvedDependents = None 96
97 - def _reset (self):
98 """CSC extension to reset fields of a Namespace. 99 100 This one handles component-resolution--related data.""" 101 getattr(super(_NamespaceResolution_mixin, self), '_reset', lambda *args, **kw: None)() 102 self.__unresolvedComponents = [] 103 self.__unresolvedDependents = {} 104 self.__importedNamespaces = set() 105 self.__referencedNamespaces = set()
106
107 - def _getState_csc (self, kw):
108 kw.update({ 109 'importedNamespaces': self.__importedNamespaces, 110 'referencedNamespaces': self.__referencedNamespaces, 111 }) 112 return getattr(super(_NamespaceResolution_mixin, self), '_getState_csc', lambda _kw: _kw)(kw)
113
114 - def _setState_csc (self, kw):
115 self.__importedNamespaces = kw['importedNamespaces'] 116 self.__referencedNamespaces = kw['referencedNamespaces'] 117 return getattr(super(_NamespaceResolution_mixin, self), '_setState_csc', lambda _kw: self)(kw)
118
119 - def importNamespace (self, namespace):
120 self.__importedNamespaces.add(namespace) 121 return self
122
123 - def _referenceNamespace (self, namespace):
124 self._activate() 125 self.__referencedNamespaces.add(namespace) 126 return self
127
128 - def importedNamespaces (self):
129 """Return the set of namespaces which some schema imported while 130 processing with this namespace as target.""" 131 return frozenset(self.__importedNamespaces)
132
133 - def _transferReferencedNamespaces (self, module_record):
134 assert isinstance(module_record, archive.ModuleRecord) 135 module_record._setReferencedNamespaces(self.__referencedNamespaces) 136 self.__referencedNamespaces.clear()
137
138 - def referencedNamespaces (self):
139 """Return the set of namespaces which appear in namespace declarations 140 of schema with this namespace as target.""" 141 return frozenset(self.__referencedNamespaces)
142
143 - def queueForResolution (self, resolvable, depends_on=None):
144 """Invoked to note that a component may have references that will need 145 to be resolved. 146 147 Newly created named components are often unresolved, as are components 148 which, in the course of resolution, are found to depend on another 149 unresolved component. 150 151 @param resolvable: An instance of L{_Resolvable_mixin} that is later to 152 be resolved. 153 154 @keyword depends_on: C{None}, or an instance of L{_Resolvable_mixin} 155 which C{resolvable} requires to be resolved in order to resolve 156 itself. 157 158 @return: C{resolvable} 159 """ 160 assert isinstance(resolvable, _Resolvable_mixin) 161 if not resolvable.isResolved(): 162 assert depends_on is None or isinstance(depends_on, _Resolvable_mixin) 163 self.__unresolvedComponents.append(resolvable) 164 if depends_on is not None and not depends_on.isResolved(): 165 from pyxb.xmlschema import structures 166 assert isinstance(depends_on, _Resolvable_mixin) 167 assert isinstance(depends_on, structures._NamedComponent_mixin) 168 self.__unresolvedDependents.setdefault(resolvable, set()).add(depends_on) 169 return resolvable
170
171 - def needsResolution (self):
172 """Return C{True} iff this namespace has not been resolved.""" 173 return self.__unresolvedComponents is not None
174
175 - def _replaceComponent_csc (self, existing_def, replacement_def):
176 """Replace a component definition if present in the list of unresolved components. 177 """ 178 try: 179 index = self.__unresolvedComponents.index(existing_def) 180 if (replacement_def is None) or (replacement_def in self.__unresolvedComponents): 181 del self.__unresolvedComponents[index] 182 else: 183 assert isinstance(replacement_def, _Resolvable_mixin) 184 self.__unresolvedComponents[index] = replacement_def 185 # Rather than assume the replacement depends on the same 186 # resolvables as the original, just wipe the dependency record: 187 # it'll get recomputed later if it's still important. 188 if existing_def in self.__unresolvedDependents: 189 del self.__unresolvedDependents[existing_def] 190 except ValueError: 191 pass 192 return getattr(super(_NamespaceResolution_mixin, self), '_replaceComponent_csc', lambda *args, **kw: replacement_def)(existing_def, replacement_def)
193
194 - def resolveDefinitions (self, allow_unresolved=False):
195 """Loop until all references within the associated resolvable objects 196 have been resolved. 197 198 This method iterates through all components on the unresolved list, 199 invoking the _resolve method of each. If the component could not be 200 resolved in this pass, it iis placed back on the list for the next 201 iteration. If an iteration completes without resolving any of the 202 unresolved components, a pyxb.NotInNamespaceError exception is raised. 203 204 @note: Do not invoke this until all top-level definitions for the 205 namespace have been provided. The resolution routines are entitled to 206 raise a validation exception if a reference to an unrecognized 207 component is encountered. 208 """ 209 if not self.needsResolution(): 210 return True 211 212 while 0 < len(self.__unresolvedComponents): 213 # Save the list of unresolved objects, reset the list to capture 214 # any new objects defined during resolution, and attempt the 215 # resolution for everything that isn't resolved. 216 unresolved = self.__unresolvedComponents 217 218 self.__unresolvedComponents = [] 219 self.__unresolvedDependents = {} 220 for resolvable in unresolved: 221 # Attempt the resolution. 222 resolvable._resolve() 223 224 # Either we resolved it, or we queued it to try again later 225 assert resolvable.isResolved() or (resolvable in self.__unresolvedComponents), 'Lost resolvable %s' % (resolvable,) 226 227 # We only clone things that have scope None. We never 228 # resolve things that have scope None. Therefore, we 229 # should never have resolved something that has 230 # clones. 231 if (resolvable.isResolved() and (resolvable._clones() is not None)): 232 assert False 233 if self.__unresolvedComponents == unresolved: 234 if allow_unresolved: 235 return False 236 # This only happens if we didn't code things right, or the 237 # there is a circular dependency in some named component 238 # (i.e., the schema designer didn't do things right). 239 failed_components = [] 240 from pyxb.xmlschema import structures 241 for d in self.__unresolvedComponents: 242 if isinstance(d, structures._NamedComponent_mixin): 243 failed_components.append('%s named %s' % (d.__class__.__name__, d.name())) 244 else: 245 failed_components.append('Anonymous %s' % (d.__class__.__name__,)) 246 raise pyxb.NotInNamespaceError('Infinite loop in resolution:\n %s' % ("\n ".join(failed_components),)) 247 248 # Replace the list of unresolved components with None, so that 249 # attempts to subsequently add another component fail. 250 self.__unresolvedComponents = None 251 self.__unresolvedDependents = None 252 253 # NOTE: Dependencies may require that we keep these around for a while 254 # longer. 255 # 256 # Remove the namespace context from everything, since we won't be 257 # resolving anything else. 258 self._releaseNamespaceContexts() 259 260 return True
261
262 - def _unresolvedComponents (self):
263 """Returns a reference to the list of unresolved components.""" 264 return self.__unresolvedComponents
265
266 - def _unresolvedDependents (self):
267 """Returns a map from unresolved components to sets of components that 268 must be resolved first.""" 269 return self.__unresolvedDependents
270
271 -def ResolveSiblingNamespaces (sibling_namespaces):
272 """Resolve all components in the sibling_namespaces. 273 274 @param sibling_namespaces : A set of namespaces expected to be closed 275 under dependency.""" 276 277 for ns in sibling_namespaces: 278 ns.configureCategories([archive.NamespaceArchive._AnonymousCategory()]) 279 ns.validateComponentModel() 280 281 def cmp_for_deps (ns1, ns2): 282 """Sort namespaces so dependencies get resolved first""" 283 if ns2 not in dependency_map.get(ns1, set()): 284 return -1 285 if ns1 not in dependency_map.get(ns2, set()): 286 return 1 287 return 0
288 289 need_resolved_set = set(sibling_namespaces) 290 dependency_map = {} 291 last_state = None 292 while need_resolved_set: 293 need_resolved_list = list(need_resolved_set) 294 if dependency_map: 295 need_resolved_list.sort(cmp_for_deps) 296 need_resolved_set = set() 297 dependency_map = {} 298 for ns in need_resolved_list: 299 if not ns.needsResolution(): 300 continue 301 if not ns.resolveDefinitions(allow_unresolved=True): 302 deps = dependency_map.setdefault(ns, set()) 303 for (c, dcs) in ns._unresolvedDependents().iteritems(): 304 for dc in dcs: 305 dns = dc.expandedName().namespace() 306 if dns != ns: 307 deps.add(dns) 308 _log.info('Holding incomplete resolution %s depending on: ', ns.uri(), ' ; '.join([ str(_dns) for _dns in deps ])) 309 need_resolved_set.add(ns) 310 # Exception termination check: if we have the same set of incompletely 311 # resolved namespaces, and each has the same number of unresolved 312 # components, assume there's an truly unresolvable dependency: either 313 # due to circularity, or because there was an external namespace that 314 # was missed from the sibling list. 315 state = [] 316 for ns in need_resolved_set: 317 state.append( (ns, len(ns._unresolvedComponents())) ) 318 state = tuple(state) 319 if last_state == state: 320 raise pyxb.LogicError('Unexpected external dependency in sibling namespaces: %s' % ("\n ".join( [str(_ns) for _ns in need_resolved_set ]),)) 321 last_state = state 322
323 -class NamespaceContext (object):
324 """Records information associated with namespaces at a DOM node. 325 """ 326
327 - def __str__ (self):
328 rv = [ 'NamespaceContext ' ] 329 if self.defaultNamespace() is not None: 330 rv.extend([ '(defaultNamespace=', str(self.defaultNamespace()), ') ']) 331 if self.targetNamespace() is not None: 332 rv.extend([ '(targetNamespace=', str(self.targetNamespace()), ') ']) 333 rv.append("\n") 334 for (pfx, ns) in self.inScopeNamespaces().items(): 335 if pfx is not None: 336 rv.append(' xmlns:%s=%s' % (pfx, str(ns))) 337 return ''.join(rv)
338 339 __TargetNamespaceAttributes = { } 340 @classmethod
341 - def _AddTargetNamespaceAttribute (cls, expanded_name, attribute_name):
342 assert expanded_name is not None 343 cls.__TargetNamespaceAttributes[expanded_name] = attribute_name
344 @classmethod
345 - def _TargetNamespaceAttribute (cls, expanded_name):
346 return cls.__TargetNamespaceAttributes.get(expanded_name, None)
347 348 # Support for holding onto referenced namespaces until we have a target 349 # namespace to give them to. 350 __pendingReferencedNamespaces = None 351
352 - def defaultNamespace (self):
353 """The default namespace in effect at this node. E.g., C{xmlns="URN:default"}.""" 354 return self.__defaultNamespace
355 __defaultNamespace = None 356 357 # If C{True}, this context is within a schema that has no target 358 # namespace, and we should use the target namespace as a fallback if no 359 # default namespace is available and no namespace prefix appears on a 360 # QName. This situation arises when a top-level schema has an absent 361 # target namespace, or when a schema with an absent target namespace is 362 # being included into a schema with a non-absent target namespace. 363 __fallbackToTargetNamespace = False 364
365 - def targetNamespace (self):
366 """The target namespace in effect at this node. Usually from the 367 C{targetNamespace} attribute. If no namespace is specified for the 368 schema, an absent namespace was assigned upon creation and will be 369 returned.""" 370 return self.__targetNamespace
371 __targetNamespace = None 372
373 - def inScopeNamespaces (self):
374 """Map from prefix strings to L{Namespace} instances associated with those 375 prefixes. The prefix C{None} identifies the default namespace.""" 376 return self.__inScopeNamespaces
377 __inScopeNamespaces = None 378
379 - def prefixForNamespace (self, namespace):
380 """Return a prefix associated with the given namespace in this 381 context, or None if the namespace is the default or is not in 382 scope.""" 383 for (pfx, ns) in self.__inScopeNamespaces.items(): 384 if namespace == ns: 385 return pfx 386 return None
387 388 @classmethod
389 - def GetNodeContext (cls, node, **kw):
390 """Get the L{NamespaceContext} instance that was assigned to the node. 391 392 If none has been assigned and keyword parameters are present, create 393 one treating this as the root node and the keyword parameters as 394 configuration information (e.g., default_namespace). 395 396 @raise pyxb.LogicError: no context is available and the keywords 397 required to create one were not provided 398 """ 399 try: 400 return node.__namespaceContext 401 except AttributeError: 402 return NamespaceContext(node, **kw)
403
404 - def setNodeContext (self, node):
405 node.__namespaceContext = self
406
407 - def processXMLNS (self, prefix, uri):
408 if not self.__mutableInScopeNamespaces: 409 self.__inScopeNamespaces = self.__inScopeNamespaces.copy() 410 self.__mutableInScopeNamespaces = True 411 if uri: 412 if prefix is None: 413 ns = self.__defaultNamespace = utility.NamespaceForURI(uri, create_if_missing=True) 414 self.__inScopeNamespaces[None] = self.__defaultNamespace 415 else: 416 ns = utility.NamespaceForURI(uri, create_if_missing=True) 417 self.__inScopeNamespaces[prefix] = ns 418 #if ns.prefix() is None: 419 # ns.setPrefix(prefix) 420 # @todo should we record prefix in namespace so we can use it 421 # during generation? I'd rather make the user specify what to 422 # use. 423 if self.__targetNamespace: 424 self.__targetNamespace._referenceNamespace(ns) 425 else: 426 self.__pendingReferencedNamespaces.add(ns) 427 else: 428 # NB: XMLNS 6.2 says that you can undefine a default 429 # namespace, but does not say anything explicitly about 430 # undefining a prefixed namespace. XML-Infoset 2.2 431 # paragraph 6 implies you can do this, but expat blows up 432 # if you try it. I don't think it's legal. 433 if prefix is not None: 434 raise pyxb.NamespaceError(self, 'Attempt to undefine non-default namespace %s' % (prefix,)) 435 self.__inScopeNamespaces.pop(prefix, None) 436 self.__defaultNamespace = None
437
438 - def finalizeTargetNamespace (self, tns_uri=None, including_context=None):
439 if tns_uri is not None: 440 assert 0 < len(tns_uri) 441 # Do not prevent overwriting target namespace; need this for WSDL 442 # files where an embedded schema inadvertently inherits a target 443 # namespace from its enclosing definitions element. Note that if 444 # we don't check this here, we do have to check it when schema 445 # documents are included into parent schema documents. 446 self.__targetNamespace = utility.NamespaceForURI(tns_uri, create_if_missing=True) 447 elif self.__targetNamespace is None: 448 if including_context is not None: 449 self.__targetNamespace = including_context.targetNamespace() 450 self.__fallbackToTargetNamespace = True 451 elif tns_uri is None: 452 self.__targetNamespace = utility.CreateAbsentNamespace() 453 else: 454 self.__targetNamespace = utility.NamespaceForURI(tns_uri, create_if_missing=True) 455 if self.__pendingReferencedNamespaces is not None: 456 [ self.__targetNamespace._referenceNamespace(_ns) for _ns in self.__pendingReferencedNamespaces ] 457 self.__pendingReferencedNamespace = None 458 assert self.__targetNamespace is not None 459 if (not self.__fallbackToTargetNamespace) and self.__targetNamespace.isAbsentNamespace(): 460 self.__fallbackToTargetNamespace = True
461
462 - def __init__ (self, 463 dom_node=None, 464 parent_context=None, 465 including_context=None, 466 recurse=True, 467 default_namespace=None, 468 target_namespace=None, 469 in_scope_namespaces=None, 470 expanded_name=None, 471 finalize_target_namespace=True): # MUST BE True for WSDL to work with minidom
472 """Determine the namespace context that should be associated with the 473 given node and, optionally, its element children. 474 475 @param dom_node: The DOM node 476 @type dom_node: C{xml.dom.Element} 477 @keyword parent_context: Optional value that specifies the context 478 associated with C{dom_node}'s parent node. If not provided, only the 479 C{xml} namespace is in scope. 480 @type parent_context: L{NamespaceContext} 481 @keyword recurse: If True (default), create namespace contexts for all 482 element children of C{dom_node} 483 @type recurse: C{bool} 484 @keyword default_namespace: Optional value to set as the default 485 namespace. Values from C{parent_context} would override this, as 486 would an C{xmlns} attribute in the C{dom_node}. 487 @type default_namespace: L{NamespaceContext} 488 @keyword target_namespace: Optional value to set as the target 489 namespace. Values from C{parent_context} would override this, as 490 would a C{targetNamespace} attribute in the C{dom_node} 491 @type target_namespace: L{NamespaceContext} 492 @keyword in_scope_namespaces: Optional value to set as the initial set 493 of in-scope namespaces. The always-present namespaces are added to 494 this if necessary. 495 @type in_scope_namespaces: C{dict} mapping C{string} to L{Namespace}. 496 """ 497 from pyxb.namespace import builtin 498 499 if dom_node is not None: 500 try: 501 assert dom_node.__namespaceContext is None 502 except AttributeError: 503 pass 504 dom_node.__namespaceContext = self 505 506 self.__defaultNamespace = default_namespace 507 self.__targetNamespace = target_namespace 508 self.__inScopeNamespaces = builtin._UndeclaredNamespaceMap 509 self.__mutableInScopeNamespaces = False 510 511 if in_scope_namespaces is not None: 512 if parent_context is not None: 513 raise pyxb.LogicError('Cannot provide both parent_context and in_scope_namespaces') 514 self.__inScopeNamespaces = builtin._UndeclaredNamespaceMap.copy() 515 self.__inScopeNamespaces.update(in_scope_namespaces) 516 self.__mutableInScopeNamespaces = True 517 518 if parent_context is not None: 519 self.__inScopeNamespaces = parent_context.inScopeNamespaces() 520 self.__mutableInScopeNamespaces = False 521 self.__defaultNamespace = parent_context.defaultNamespace() 522 self.__targetNamespace = parent_context.targetNamespace() 523 self.__fallbackToTargetNamespace = parent_context.__fallbackToTargetNamespace 524 525 if self.__targetNamespace is None: 526 self.__pendingReferencedNamespaces = set() 527 attribute_map = {} 528 if dom_node is not None: 529 if expanded_name is None: 530 expanded_name = pyxb.namespace.ExpandedName(dom_node) 531 for ai in range(dom_node.attributes.length): 532 attr = dom_node.attributes.item(ai) 533 if builtin.XMLNamespaces.uri() == attr.namespaceURI: 534 prefix = attr.localName 535 if 'xmlns' == prefix: 536 prefix = None 537 self.processXMLNS(prefix, attr.value) 538 else: 539 if attr.namespaceURI is not None: 540 uri = utility.NamespaceForURI(attr.namespaceURI, create_if_missing=True) 541 key = pyxb.namespace.ExpandedName(uri, attr.localName) 542 else: 543 key = pyxb.namespace.ExpandedName(None, attr.localName) 544 attribute_map[key] = attr.value 545 546 if finalize_target_namespace: 547 tns_uri = None 548 tns_attr = self._TargetNamespaceAttribute(expanded_name) 549 if tns_attr is not None: 550 tns_uri = attribute_map.get(tns_attr) 551 self.finalizeTargetNamespace(tns_uri, including_context=including_context) 552 553 # Store in each node the in-scope namespaces at that node; 554 # we'll need them for QName interpretation of attribute 555 # values. 556 if (dom_node is not None) and recurse: 557 from xml.dom import Node 558 assert Node.ELEMENT_NODE == dom_node.nodeType 559 for cn in dom_node.childNodes: 560 if Node.ELEMENT_NODE == cn.nodeType: 561 NamespaceContext(cn, self, True)
562
563 - def interpretQName (self, name, namespace=None):
564 """Convert the provided name into an L{ExpandedName}, i.e. a tuple of 565 L{Namespace} and local name. 566 567 If the name includes a prefix, that prefix must map to an in-scope 568 namespace in this context. Absence of a prefix maps to 569 L{defaultNamespace()}, which must be provided (or defaults to the 570 target namespace, if that is absent). 571 572 @param name: A QName. 573 @type name: C{str} or C{unicode} 574 @param name: Optional namespace to use for unqualified names when 575 there is no default namespace. Note that a defined default namespace, 576 even if absent, supersedes this value. 577 @return: An L{ExpandedName} tuple: ( L{Namespace}, C{str} ) 578 @raise pyxb.SchemaValidationError: The prefix is not in scope 579 @raise pyxb.SchemaValidationError: No prefix is given and the default namespace is absent 580 """ 581 assert isinstance(name, (str, unicode)) 582 if 0 <= name.find(':'): 583 (prefix, local_name) = name.split(':', 1) 584 assert self.inScopeNamespaces() is not None 585 namespace = self.inScopeNamespaces().get(prefix) 586 if namespace is None: 587 raise pyxb.SchemaValidationError('No namespace declared for QName %s prefix' % (name,)) 588 else: 589 local_name = name 590 # Context default supersedes caller-provided namespace 591 if self.defaultNamespace() is not None: 592 namespace = self.defaultNamespace() 593 # If there's no default namespace, but there is a fallback 594 # namespace, use that instead. 595 if (namespace is None) and self.__fallbackToTargetNamespace: 596 namespace = self.targetNamespace() 597 if namespace is None: 598 raise pyxb.SchemaValidationError('QName %s with absent default namespace cannot be resolved' % (local_name,)) 599 # Anything we're going to look stuff up in requires a component model. 600 # Make sure we can load one, unless we're looking up in the thing 601 # we're constructing (in which case it's being built right now). 602 if (namespace != self.targetNamespace()): 603 namespace.validateComponentModel() 604 return pyxb.namespace.ExpandedName(namespace, local_name)
605
606 - def queueForResolution (self, component, depends_on=None):
607 """Forwards to L{queueForResolution()<Namespace.queueForResolution>} in L{targetNamespace()}.""" 608 assert isinstance(component, _Resolvable_mixin) 609 return self.targetNamespace().queueForResolution(component, depends_on)
610 611 ## Local Variables: 612 ## fill-column:78 613 ## End: 614