1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """Classes and global objects related to U{XML Namespaces<http://www.w3.org/TR/2006/REC-xml-names-20060816/index.html>}.
17
18 Since namespaces hold all referenceable objects, this module also defines the
19 infrastructure for resolving named object references, such as schema
20 components.
21 """
22
23 import pyxb
24 import pyxb.utils.utility
25 from pyxb.utils import six
26 import xml.dom
27 import logging
28
29 _log = logging.getLogger(__name__)
30
31 @pyxb.utils.utility.BackfillComparisons
33
34 """Represent an U{expanded name
35 <http://www.w3.org/TR/REC-xml-names/#dt-expname>}, which pairs a
36 namespace with a local name.
37
38 Because a large number of local elements, and most attributes, have no
39 namespace associated with them, this is optimized for representing names
40 with an absent namespace. The hash and equality test methods are set so
41 that a plain string is equivalent to a tuple of C{None} and that string.
42
43 Note that absent namespaces can be represented in two ways: with a
44 namespace of C{None} (the name "has no namespace"), and with a namespace
45 that is an L{absent namespace <Namespace.CreateAbsentNamespace>} (the name
46 "has an absent namespace"). Hash code calculations are done so that the
47 two alternatives produce the same hash; however, comparison is done so
48 that the two are distinguished. The latter is the intended behavior; the
49 former should not be counted upon.
50
51 This class allows direct lookup of the named object within a category by
52 using the category name as an accessor function. That is, if the
53 namespace of the expanded name C{en} has a category 'typeDefinition', then
54 the following two expressions are equivalent::
55
56 en.typeDefinition()
57 en.namespace().categoryMap('typeDefinition').get(en.localName())
58
59 This class descends from C{tuple} so that its values can be used as
60 dictionary keys without concern for pointer equivalence.
61 """
63 """The L{Namespace} part of the expanded name."""
64 return self.__namespace
65 __namespace = None
66
68 """Return the URI of the namespace, or C{None} if the namespace is absent."""
69 return self.__namespaceURI
70 __namespaceURI = None
71
73 """The local part of the expanded name."""
74 return self.__localName
75 __localName = None
76
77
78 __expandedName = None
79
83
85 """Return a tuple consisting of the namespace URI and the local name.
86
87 This presents the expanded name as base Python types for persistent
88 storage. Be aware, though, that it will lose the association of the
89 name with an absent namespace, if that matters to you."""
90 return ( self.__namespaceURI, self.__localName )
91
92
106
108 """Return a new expanded name in the namespace of this name.
109
110 @param local_name: The local name portion of an expanded name.
111 @return: An instance of L{ExpandedName}.
112 """
113 return ExpandedName(self.namespace(), local_name)
114
116 """Return the input name, except if the input name has no namespace,
117 return a name that uses the namespace from this name with the local
118 name from the input name.
119
120 Use this when the XML document has an unqualified name and we're
121 processing using an absent default namespace.
122
123 @warning: Be careful when using a global name to adopt a name from a
124 local element: if the local element (with no namespace) has the same
125 localName as but is different from the global element (with a
126 namespace), this will improperly provide a namespace when one should
127 not be present. See the comments in
128 L{pyxb.binding.basis.element.elementForName}.
129 """
130
131 if not isinstance(name, ExpandedName):
132 name = ExpandedName(name)
133 if name.namespace() is None:
134 name = self.createName(name.localName())
135 return name
136
138 """Create an expanded name.
139
140 Expected argument patterns are:
141
142 - ( C{str} ) : the local name in an absent namespace
143 - ( L{ExpandedName} ) : a copy of the given expanded name
144 - ( C{xml.dom.Node} ) : The name extracted from node.namespaceURI and node.localName
145 - ( C{str}, C{str} ) : the namespace URI and the local name
146 - ( L{Namespace}, C{str} ) : the namespace and the local name
147 - ( L{ExpandedName}, C{str}) : the namespace from the expanded name, and the local name
148
149 Wherever C{str} occurs C{unicode} is also permitted.
150
151 @keyword fallback_namespace: Optional Namespace instance to use if the
152 namespace would otherwise be None. This is only used if it is an
153 absent namespace.
154
155 """
156 fallback_namespace = kw.get('fallback_namespace')
157 if 0 == len(args):
158 raise pyxb.LogicError('Too few arguments to ExpandedName constructor')
159 if 2 < len(args):
160 raise pyxb.LogicError('Too many arguments to ExpandedName constructor')
161 if 2 == len(args):
162
163 ( ns, ln ) = args
164 else:
165
166 assert 1 == len(args)
167 ln = args[0]
168 ns = None
169 if isinstance(ln, six.string_types):
170 pass
171 elif isinstance(ln, tuple) and (2 == len(ln)):
172 (ns, ln) = ln
173 elif isinstance(ln, ExpandedName):
174 ns = ln.namespace()
175 ln = ln.localName()
176 elif isinstance(ln, xml.dom.Node):
177 if not(ln.nodeType in (xml.dom.Node.ELEMENT_NODE, xml.dom.Node.ATTRIBUTE_NODE)):
178 raise pyxb.LogicError('Cannot create expanded name from non-element DOM node %s' % (ln.nodeType,))
179 ns = ln.namespaceURI
180 ln = ln.localName
181 else:
182 raise pyxb.LogicError('Unrecognized argument type %s' % (type(ln),))
183 if (ns is None) and (fallback_namespace is not None):
184 if fallback_namespace.isAbsentNamespace():
185 ns = fallback_namespace
186 if isinstance(ns, six.string_types):
187 ns = NamespaceForURI(ns, create_if_missing=True)
188 if isinstance(ns, ExpandedName):
189 ns = ns.namespace()
190 if (ns is not None) and not isinstance(ns, Namespace):
191 raise pyxb.LogicError('ExpandedName must include a valid (perhaps absent) namespace, or None.')
192 self.__namespace = ns
193 if self.__namespace is not None:
194 self.__namespaceURI = self.__namespace.uri()
195 self.__localName = ln
196 assert self.__localName is not None
197 self.__expandedName = ( self.__namespace, self.__localName )
198 self.__uriTuple = ( self.__namespaceURI, self.__localName )
199 super(ExpandedName, self).__init__(*args, **kw)
200
206
212
214 if isinstance(other, six.string_types):
215 other = ( None, other )
216 if not isinstance(other, tuple):
217 other = other.__uriTuple
218 if isinstance(other[0], Namespace):
219 other = ( other[0].uri(), other[1] )
220 return other
221
226
231
241
245
247 """An extended dictionary intended to assist with QName resolution.
248
249 These dictionaries have an attribute that identifies a category of named
250 objects within a Namespace; the specifications for various documents
251 require that certain groups of objects must be unique, while uniqueness is
252 not required between groups. The dictionary also retains a pointer to the
253 Namespace instance for which it holds objects."""
255 """The namespace to which the object map belongs."""
256 return self.__namespace
257 __namespace = None
258
260 """The category of objects (e.g., typeDefinition, elementDeclaration)."""
261 return self.__category
262 __category = None
263
264 - def __init__ (self, category, namespace, *args, **kw):
268
270 """Mix-in that aggregates those aspects of XMLNamespaces that hold
271 references to categories of named objects.
272
273 Arbitrary groups of named objects, each requiring unique names within
274 themselves, can be saved. Unless configured otherwise, the Namespace
275 instance is extended with accessors that provide direct access to
276 individual category maps. The name of the method is the category name
277 with a suffix of "s"; e.g., if a category "typeDefinition" exists, it can
278 be accessed from the namespace using the syntax C{ns.typeDefinitions()}.
279
280 Note that the returned value from the accessor is a live reference to
281 the category map; changes made to the map are reflected in the
282 namespace.
283 """
284
285
286
287 __categoryMap = None
288
290 """CSC extension to reset fields of a Namespace.
291
292 This one handles category-related data."""
293 getattr(super(_NamespaceCategory_mixin, self), '_reset', lambda *args, **kw: None)()
294 self.__categoryMap = { }
295
297 """The list of individual categories held in this namespace."""
298 return list(self.__categoryMap.keys())
299
301 """Return the whole map from categories to named objects."""
302 return self.__categoryMap
303
310
312 """Define public methods on the Namespace which provide access to
313 individual NamedObjectMaps based on their category.
314
315 """
316 for category in self.categories():
317 accessor_name = category + 's'
318 setattr(self, accessor_name, lambda _map=self.categoryMap(category): _map)
319
336
338 """Allow access to the named_object by looking up the local_name in
339 the given category.
340
341 Raises pyxb.NamespaceUniquenessError if an object with the same name
342 already exists in the category."""
343 name_map = self.categoryMap(category)
344 old_object = name_map.get(local_name)
345 if (old_object is not None) and (old_object != named_object):
346 raise pyxb.NamespaceUniquenessError(self, '%s: name %s used for multiple values in %s' % (self, local_name, category))
347 name_map[local_name] = named_object
348 return named_object
349
351 """Replace the referenced object in the category.
352
353 The new object will be added only if the old_object matches the
354 current entry for local_name in the category."""
355 name_map = self.categoryMap(category)
356 if old_object == name_map.get(local_name):
357 name_map[local_name] = new_object
358 return name_map[local_name]
359
361 """Replace a component definition where present in the category maps.
362
363 @note: This is a high-cost operation, as every item in every category
364 map must be examined to see whether its value field matches
365 C{existing_def}."""
366 for (cat, registry) in six.iteritems(self.__categoryMap):
367 for (k, v) in registry.items():
368 if v == existing_def:
369 del registry[k]
370 if replacement_def is not None:
371 registry[k] = replacement_def
372 return getattr(super(_NamespaceCategory_mixin, self), '_replaceComponent_csc', lambda *args, **kw: replacement_def)(existing_def, replacement_def)
373
374
375
376
377
378
389
395
397 """Add the named objects from the given map into the set held by this namespace.
398 It is an error to name something which is already present."""
399 self.configureCategories(six.iterkeys(category_map))
400 for category in six.iterkeys(category_map):
401 current_map = self.categoryMap(category)
402 new_map = category_map[category]
403 for (local_name, component) in six.iteritems(new_map):
404 existing_component = current_map.get(local_name)
405 if existing_component is None:
406 current_map[local_name] = component
407 elif existing_component._allowUpdateFromOther(component):
408 existing_component._updateFromOther(component)
409 else:
410 raise pyxb.NamespaceError(self, 'Load attempted to override %s %s in %s' % (category, local_name, self.uri()))
411 self.__defineCategoryAccessors()
412
414 """Return C{True} iff schema components have been associated with this namespace.
415
416 This only checks whether the corresponding categories have been added,
417 not whether there are any entries in those categories. It is useful
418 for identifying namespaces that were incorporated through a
419 declaration but never actually referenced."""
420 return 'typeDefinition' in self.__categoryMap
421
440
442 """Mix-in for components that can depend on other components."""
443
444 __PrivateTransient = set()
445
446
447 __bindingRequires = None
448 __PrivateTransient.add('bindingRequires')
449
451 """CSC extension to reset fields of a component. This one clears
452 dependency-related data, since the clone will have to revise its
453 dependencies.
454 @rtype: C{None}"""
455 getattr(super(_ComponentDependency_mixin, self), '_resetClone_csc', lambda *_args, **_kw: None)(**kw)
456 self.__bindingRequires = None
457
459 """Return a set of components upon whose bindings this component's
460 bindings depend.
461
462 For example, bindings that are extensions or restrictions depend on
463 their base types. Complex type definition bindings require that the
464 types of their attribute declarations be available at the class
465 definition, and the types of their element declarations in the
466 postscript.
467
468 @keyword include_lax: if C{False} (default), only the requirements of
469 the class itself are returned. If C{True}, all requirements are
470 returned.
471 @rtype: C{set(L{pyxb.xmlschema.structures._SchemaComponent_mixin})}
472 """
473 if reset or (self.__bindingRequires is None):
474 if isinstance(self, resolution._Resolvable_mixin) and not (self.isResolved()):
475 raise pyxb.LogicError('Unresolved %s in %s: %s' % (self.__class__.__name__, self._namespaceContext().targetNamespace(), self.name()))
476 self.__bindingRequires = self._bindingRequires_vx(include_lax)
477 return self.__bindingRequires
478
480 """Placeholder for subclass method that identifies the necessary components.
481
482 @note: Override in subclasses.
483
484 @return: The component instances on which this component depends
485 @rtype: C{frozenset}
486 @raise LogicError: A subclass failed to implement this method
487 """
488 raise pyxb.LogicError('%s does not implement _bindingRequires_vx' % (type(self),))
489
491 """Mix-in for managing components defined within this namespace.
492
493 The component set includes not only top-level named components (such as
494 those accessible through category maps), but internal anonymous
495 components, such as those involved in representing the content model of a
496 complex type definition. We need to be able to get a list of these
497 components, sorted in dependency order, so that generated bindings do not
498 attempt to refer to a binding that has not yet been generated."""
499
500
501
502 __components = None
503
505 """CSC extension to reset fields of a Namespace.
506
507 This one handles data related to component association with a
508 namespace."""
509 getattr(super(_NamespaceComponentAssociation_mixin, self), '_reset', lambda *args, **kw: None)()
510 self.__components = set()
511 self.__origins = set()
512 self.__schemaMap = { }
513
521
523 """Replace a component definition in the set of associated components.
524
525 @raise KeyError: C{existing_def} is not in the set of components."""
526
527 self.__components.remove(existing_def)
528 if replacement_def is not None:
529 self.__components.add(replacement_def)
530 return getattr(super(_NamespaceComponentAssociation_mixin, self), '_replaceComponent_csc', lambda *args, **kw: replacement_def)(existing_def, replacement_def)
531
541
550
557
558 __origins = None
559
561 """Return a frozenset of all components, named or unnamed, belonging
562 to this namespace."""
563 return frozenset(self.__components)
564
568
569 from pyxb.namespace import archive
570 from pyxb.namespace.utility import NamespaceInstance
571 from pyxb.namespace.utility import NamespaceForURI
572 from pyxb.namespace.utility import CreateAbsentNamespace
573 from pyxb.namespace.utility import AvailableNamespaces
574 from pyxb.namespace import resolution
575 NamespaceContext = resolution.NamespaceContext
576
577 -class Namespace (_NamespaceCategory_mixin, resolution._NamespaceResolution_mixin, _NamespaceComponentAssociation_mixin, archive._NamespaceArchivable_mixin):
578 """Represents an XML namespace (a URI).
579
580 There is at most one L{Namespace} class instance per namespace (URI). The
581 instance also supports associating arbitrary L{maps<NamedObjectMap>} from
582 names to objects, in separate categories. The default categories are
583 configured externally; for example, the
584 L{Schema<pyxb.xmlschema.structures.Schema>} component defines a category
585 for each named component in XMLSchema, and the customizing subclass for
586 WSDL definitions adds categories for the service bindings, messages, etc.
587
588 Namespaces can be written to and loaded from pickled files. See
589 L{NamespaceArchive} for information.
590 """
591
592
593
594 __uri = None
595
596
597
598
599
600
601
602 __absentNamespaceID = 0
603
604
605
606 __boundPrefix = None
607
608
609
610 __prefix = None
611
612
613
614 __Registry = { }
615
616
617 __AbsentNamespaces = set()
618
619
620 __description = None
621
622
623 __isBuiltinNamespace = False
624
625
626 __isUndeclaredNamespace = False
627
628
629 __isLoadedNamespace = False
630
631
632
633 __namespaceArchive = None
634
635
636 __hasBeenArchived = False
637
638
639
640 __builtinModulePath = None
641
642
643
644
645 __bindingConfiguration = None
646
647
648
649
650
651
652 __initialNamespaceContext = None
653
654
655
656 __contextDefaultNamespace = None
657
658
659
660 __contextInScopeNamespaces = None
661
662 @classmethod
664 """If a Namespace instance for the given URI exists, return it; otherwise return None.
665
666 Note: Absent namespaces are not stored in the registry. If you use
667 one (e.g., for a schema with no target namespace), don't lose hold of
668 it."""
669 if uri is None:
670 raise pyxb.UsageError('Absent namespaces are unlocatable')
671 return cls.__Registry.get(uri)
672
673
674
675
676 __AbsentNamespaceRegistry = { }
677
678
679
680
681 __absentSerializedUUID = None
682
683 __SerializedVariantAbsent = 'absent'
684
703
732
733 @classmethod
737
738 - def __init__ (self, uri,
739 description=None,
740 builtin_namespace=None,
741 builtin_module_path=None,
742 is_undeclared_namespace=False,
743 is_loaded_namespace=False,
744 bound_prefix=None,
745 default_namespace=None,
746 in_scope_namespaces=None):
784
789
791 """Return the URI for the namespace represented by this instance.
792
793 If the URI is None, this is an absent namespace, used to hold
794 declarations not associated with a namespace (e.g., from schema with
795 no target namespace)."""
796 return self.__uri
797
805
810
812 """Return True iff this namespace is an absent namespace.
813
814 Absent namespaces have no namespace URI; they exist only to
815 hold components created from schemas with no target
816 namespace."""
817 return self.__uri is None
818
820 """When known to be operating in this namespace, provide the Namespace
821 instance to be used when names are associated with no namespace."""
822 if self.isAbsentNamespace():
823 return self
824 return None
825
826 @classmethod
837
841
843 """Return the standard prefix to be used for this namespace.
844
845 Only a few namespace prefixes are bound to namespaces: xml and xmlns
846 are two. In all other cases, this method should return None. The
847 infrastructure attempts to prevent user creation of Namespace
848 instances that have bound prefixes."""
849 return self.__boundPrefix
850
852 """Return True iff this namespace was defined by the infrastructure.
853
854 That is the case for all namespaces in the Namespace module."""
855 return self.__isBuiltinNamespace
856
858 assert self.__builtinNamespaceVariable is not None
859 return 'pyxb.namespace.%s' % (self.__builtinNamespaceVariable,)
860
869
871 """Return True iff this namespace is always available
872 regardless of whether there is a declaration for it.
873
874 This is the case only for the
875 xml(http://www.w3.org/XML/1998/namespace) and
876 xmlns(http://www.w3.org/2000/xmlns/) namespaces."""
877 return self.__isUndeclaredNamespace
878
880 """Return C{True} iff this namespace was loaded from a namespace archive."""
881 return self.__isLoadedNamespace
882
884 """Return C{True} iff this namespace has been saved to a namespace archive.
885 See also L{isLoadedNamespace}."""
886 return self.__hasBeenArchived
887
893
896
899
901 """Support pickling.
902
903 Well, no, not really. Because namespace instances must be unique, we
904 represent them as their URI, and that's done by __getnewargs__
905 above. All the interesting information is in the ModuleRecords."""
906 return {}
907
910
911 __definedBuiltins = False
921
923 """Attempts to load the named objects held in this namespace.
924
925 The base class implementation looks at the set of available archived
926 namespaces, and if one contains this namespace unserializes its named
927 object maps.
928
929 Sub-classes may choose to look elsewhere, if this version fails or
930 before attempting it.
931
932 There is no guarantee that any particular category of named object has
933 been located when this returns. Caller must check.
934 """
935 for mr in self.moduleRecords():
936 if mr.isLoadable():
937 if mr.isPublic():
938 _log.info('Load %s from %s', mr, mr.archive())
939 try:
940 mr.archive().readNamespaces()
941 except pyxb.NamespaceArchiveError:
942 _log.exception("Failure reading namespaces in archive")
943 else:
944 _log.info('Ignoring private module %s in validation', mr)
945 self._activate()
946
947 __didValidation = False
948 __inValidation = False
968
970 """Replace the existing definition with another.
971
972 This is used in a situation where building the component model
973 resulted in a new component instance being created and registered, but
974 for which an existing component is to be preferred. An example is
975 when parsing the schema for XMLSchema itself: the built-in datatype
976 components should be retained instead of the simple type definition
977 components dynamically created from the schema.
978
979 By providing the value C{None} as the replacement definition, this can
980 also be used to remove components.
981
982 @note: Invoking this requires scans of every item in every category
983 map in the namespace.
984
985 @return: C{replacement_def}
986 """
987
988
989 return self._replaceComponent_csc(existing_def, replacement_def)
990
992 """Obtain the namespace context to be used when creating components in this namespace.
993
994 Usually applies only to built-in namespaces, but is also used in the
995 autotests when creating a namespace without a xs:schema element. .
996 Note that we must create the instance dynamically, since the
997 information that goes into it has cross-dependencies that can't be
998 resolved until this module has been completely loaded."""
999
1000 if self.__initialNamespaceContext is None:
1001 isn = { }
1002 if self.__contextInScopeNamespaces is not None:
1003 for (k, v) in six.iteritems(self.__contextInScopeNamespaces):
1004 isn[k] = self.__identifyNamespace(v)
1005 kw = { 'target_namespace' : self
1006 , 'default_namespace' : self.__identifyNamespace(self.__contextDefaultNamespace)
1007 , 'in_scope_namespaces' : isn }
1008 self.__initialNamespaceContext = resolution.NamespaceContext(None, **kw)
1009 return self.__initialNamespaceContext
1010
1011
1013 """Identify the specified namespace, which should be a built-in.
1014
1015 Normally we can just use a reference to the Namespace module instance,
1016 but when creating those instances we sometimes need to refer to ones
1017 for which the instance has not yet been created. In that case, we use
1018 the name of the instance, and resolve the namespace when we need to
1019 create the initial context."""
1020 if nsval is None:
1021 return self
1022 if isinstance(nsval, six.string_types):
1023 nsval = globals().get(nsval)
1024 if isinstance(nsval, Namespace):
1025 return nsval
1026 raise pyxb.LogicError('Cannot identify namespace from %s' % (nsval,))
1027
1037
1038 from pyxb.namespace.builtin import XMLSchema_instance
1039 from pyxb.namespace.builtin import XMLNamespaces
1040 from pyxb.namespace.builtin import XMLSchema
1041 from pyxb.namespace.builtin import XHTML
1042 from pyxb.namespace.builtin import XML
1043 from pyxb.namespace.builtin import XMLSchema_hfp
1044 from pyxb.namespace.builtin import BuiltInObjectUID
1045
1046 resolution.NamespaceContext._AddTargetNamespaceAttribute(XMLSchema.createExpandedName('schema'), ExpandedName('targetNamespace'))
1047
1048
1049
1050
1051