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 import xml.dom
26 import logging
27
28 _log = logging.getLogger(__name__)
31
32 """Represent an U{expanded name
33 <http://www.w3.org/TR/REC-xml-names/#dt-expname>}, which pairs a
34 namespace with a local name.
35
36 Because a large number of local elements, and most attributes, have no
37 namespace associated with them, this is optimized for representing names
38 with an absent namespace. The hash and equality test methods are set so
39 that a plain string is equivalent to a tuple of C{None} and that string.
40
41 Note that absent namespaces can be represented in two ways: with a
42 namespace of C{None} (the name "has no namespace"), and with a namespace
43 that is an L{absent namespace <Namespace.CreateAbsentNamespace>} (the name
44 "has an absent namespace"). Hash code calculations are done so that the
45 two alternatives produce the same hash; however, comparison is done so
46 that the two are distinguished. The latter is the intended behavior; the
47 former should not be counted upon.
48
49 This class allows direct lookup of the named object within a category by
50 using the category name as an accessor function. That is, if the
51 namespace of the expanded name C{en} has a category 'typeDefinition', then
52 the following two expressions are equivalent::
53
54 en.typeDefinition()
55 en.namespace().categoryMap('typeDefinition').get(en.localName())
56
57 This class descends from C{tuple} so that its values can be used as
58 dictionary keys without concern for pointer equivalence.
59 """
61 """The L{Namespace} part of the expanded name."""
62 return self.__namespace
63 __namespace = None
64
66 """Return the URI of the namespace, or C{None} if the namespace is absent."""
67 return self.__namespaceURI
68 __namespaceURI = None
69
71 """The local part of the expanded name."""
72 return self.__localName
73 __localName = None
74
75
76 __expandedName = None
77
81
83 """Return a tuple consisting of the namespace URI and the local name.
84
85 This presents the expanded name as base Python types for persistent
86 storage. Be aware, though, that it will lose the association of the
87 name with an absent namespace, if that matters to you."""
88 return ( self.__namespaceURI, self.__localName )
89
90
100
102 """Return a new expanded name in the namespace of this name.
103
104 @param local_name: The local name portion of an expanded name.
105 @return: An instance of L{ExpandedName}.
106 """
107 return ExpandedName(self.namespace(), local_name)
108
110 """Return the input name, except if the input name has no namespace,
111 return a name that uses the namespace from this name with the local
112 name from the input name.
113
114 Use this when the XML document has an unqualified name and we're
115 processing using an absent default namespace.
116
117 @warning: Be careful when using a global name to adopt a name from a
118 local element: if the local element (with no namespace) has the same
119 localName as but is different from the global element (with a
120 namespace), this will improperly provide a namespace when one should
121 not be present. See the comments in
122 L{pyxb.binding.basis.element.elementForName}.
123 """
124
125 if not isinstance(name, ExpandedName):
126 name = ExpandedName(name)
127 if name.namespace() is None:
128 name = self.createName(name.localName())
129 return name
130
132 """Create an expanded name.
133
134 Expected argument patterns are:
135
136 - ( C{str} ) : the local name in an absent namespace
137 - ( L{ExpandedName} ) : a copy of the given expanded name
138 - ( C{xml.dom.Node} ) : The name extracted from node.namespaceURI and node.localName
139 - ( C{str}, C{str} ) : the namespace URI and the local name
140 - ( L{Namespace}, C{str} ) : the namespace and the local name
141 - ( L{ExpandedName}, C{str}) : the namespace from the expanded name, and the local name
142
143 Wherever C{str} occurs C{unicode} is also permitted.
144
145 @keyword fallback_namespace: Optional Namespace instance to use if the
146 namespace would otherwise be None. This is only used if it is an
147 absent namespace.
148
149 """
150 fallback_namespace = kw.get('fallback_namespace')
151 if 0 == len(args):
152 raise pyxb.LogicError('Too few arguments to ExpandedName constructor')
153 if 2 < len(args):
154 raise pyxb.LogicError('Too many arguments to ExpandedName constructor')
155 if 2 == len(args):
156
157 ( ns, ln ) = args
158 else:
159
160 assert 1 == len(args)
161 ln = args[0]
162 ns = None
163 if isinstance(ln, basestring):
164 pass
165 elif isinstance(ln, tuple) and (2 == len(ln)):
166 (ns, ln) = ln
167 elif isinstance(ln, ExpandedName):
168 ns = ln.namespace()
169 ln = ln.localName()
170 elif isinstance(ln, xml.dom.Node):
171 if not(ln.nodeType in (xml.dom.Node.ELEMENT_NODE, xml.dom.Node.ATTRIBUTE_NODE)):
172 raise pyxb.LogicError('Cannot create expanded name from non-element DOM node %s' % (ln.nodeType,))
173 ns = ln.namespaceURI
174 ln = ln.localName
175 else:
176 raise pyxb.LogicError('Unrecognized argument type %s' % (type(ln),))
177 if (ns is None) and (fallback_namespace is not None):
178 if fallback_namespace.isAbsentNamespace():
179 ns = fallback_namespace
180 if isinstance(ns, (str, unicode)):
181 ns = NamespaceForURI(ns, create_if_missing=True)
182 if isinstance(ns, ExpandedName):
183 ns = ns.namespace()
184 if (ns is not None) and not isinstance(ns, Namespace):
185 raise pyxb.LogicError('ExpandedName must include a valid (perhaps absent) namespace, or None.')
186 self.__namespace = ns
187 if self.__namespace is not None:
188 self.__namespaceURI = self.__namespace.uri()
189 self.__localName = ln
190 assert self.__localName is not None
191 self.__expandedName = ( self.__namespace, self.__localName )
192 self.__uriTuple = ( self.__namespaceURI, self.__localName )
193
194
200
206
208 if other is None:
209 return cmp(1, -1)
210 if isinstance(other, (str, unicode)):
211 other = ( None, other )
212 if not isinstance(other, tuple):
213 other = other.__uriTuple
214 if isinstance(other[0], Namespace):
215 other = ( other[0].uri(), other[1] )
216 return cmp(self.__uriTuple, other)
217
227
231
233 """An extended dictionary intended to assist with QName resolution.
234
235 These dictionaries have an attribute that identifies a category of named
236 objects within a Namespace; the specifications for various documents
237 require that certain groups of objects must be unique, while uniqueness is
238 not required between groups. The dictionary also retains a pointer to the
239 Namespace instance for which it holds objects."""
241 """The namespace to which the object map belongs."""
242 return self.__namespace
243 __namespace = None
244
246 """The category of objects (e.g., typeDefinition, elementDeclaration)."""
247 return self.__category
248 __category = None
249
250 - def __init__ (self, category, namespace, *args, **kw):
254
256 """Mix-in that aggregates those aspects of XMLNamespaces that hold
257 references to categories of named objects.
258
259 Arbitrary groups of named objects, each requiring unique names within
260 themselves, can be saved. Unless configured otherwise, the Namespace
261 instance is extended with accessors that provide direct access to
262 individual category maps. The name of the method is the category name
263 with a suffix of "s"; e.g., if a category "typeDefinition" exists, it can
264 be accessed from the namespace using the syntax C{ns.typeDefinitions()}.
265
266 Note that the returned value from the accessor is a live reference to
267 the category map; changes made to the map are reflected in the
268 namespace.
269 """
270
271
272
273 __categoryMap = None
274
276 """CSC extension to reset fields of a Namespace.
277
278 This one handles category-related data."""
279 getattr(super(_NamespaceCategory_mixin, self), '_reset', lambda *args, **kw: None)()
280 self.__categoryMap = { }
281
283 """The list of individual categories held in this namespace."""
284 return self.__categoryMap.keys()
285
287 """Return the whole map from categories to named objects."""
288 return self.__categoryMap
289
296
298 """Define public methods on the Namespace which provide access to
299 individual NamedObjectMaps based on their category.
300
301 """
302 for category in self.categories():
303 accessor_name = category + 's'
304 setattr(self, accessor_name, lambda _map=self.categoryMap(category): _map)
305
322
324 """Allow access to the named_object by looking up the local_name in
325 the given category.
326
327 Raises pyxb.NamespaceUniquenessError if an object with the same name
328 already exists in the category."""
329 name_map = self.categoryMap(category)
330 old_object = name_map.get(local_name)
331 if (old_object is not None) and (old_object != named_object):
332 raise pyxb.NamespaceUniquenessError(self, '%s: name %s used for multiple values in %s' % (self, local_name, category))
333 name_map[local_name] = named_object
334 return named_object
335
337 """Replace the referenced object in the category.
338
339 The new object will be added only if the old_object matches the
340 current entry for local_name in the category."""
341 name_map = self.categoryMap(category)
342 if old_object == name_map.get(local_name):
343 name_map[local_name] = new_object
344 return name_map[local_name]
345
347 """Replace a component definition where present in the category maps.
348
349 @note: This is a high-cost operation, as every item in every category
350 map must be examined to see whether its value field matches
351 C{existing_def}."""
352 for (cat, registry) in self.__categoryMap.items():
353 for (k, v) in registry.items():
354 if v == existing_def:
355 del registry[k]
356 if replacement_def is not None:
357 registry[k] = replacement_def
358 return getattr(super(_NamespaceCategory_mixin, self), '_replaceComponent_csc', lambda *args, **kw: replacement_def)(existing_def, replacement_def)
359
360
361
362
363
364
375
381
383 """Add the named objects from the given map into the set held by this namespace.
384 It is an error to name something which is already present."""
385 self.configureCategories(category_map.keys())
386 for category in category_map.keys():
387 current_map = self.categoryMap(category)
388 new_map = category_map[category]
389 for (local_name, component) in new_map.iteritems():
390 existing_component = current_map.get(local_name)
391 if existing_component is None:
392 current_map[local_name] = component
393 elif existing_component._allowUpdateFromOther(component):
394 existing_component._updateFromOther(component)
395 else:
396 raise pyxb.NamespaceError(self, 'Load attempted to override %s %s in %s' % (category, local_name, self.uri()))
397 self.__defineCategoryAccessors()
398
400 """Return C{True} iff schema components have been associated with this namespace.
401
402 This only checks whether the corresponding categories have been added,
403 not whether there are any entries in those categories. It is useful
404 for identifying namespaces that were incorporated through a
405 declaration but never actually referenced."""
406 return 'typeDefinition' in self.__categoryMap
407
426
428 """Mix-in for components that can depend on other components."""
429
430 __PrivateTransient = set()
431
432
433 __bindingRequires = None
434 __PrivateTransient.add('bindingRequires')
435
437 """CSC extension to reset fields of a component. This one clears
438 dependency-related data, since the clone will have to revise its
439 dependencies.
440 @rtype: C{None}"""
441 getattr(super(_ComponentDependency_mixin, self), '_resetClone_csc', lambda *_args, **_kw: None)(**kw)
442 self.__bindingRequires = None
443
445 """Return a set of components upon whose bindings this component's
446 bindings depend.
447
448 For example, bindings that are extensions or restrictions depend on
449 their base types. Complex type definition bindings require that the
450 types of their attribute declarations be available at the class
451 definition, and the types of their element declarations in the
452 postscript.
453
454 @keyword include_lax: if C{False} (default), only the requirements of
455 the class itself are returned. If C{True}, all requirements are
456 returned.
457 @rtype: C{set(L{pyxb.xmlschema.structures._SchemaComponent_mixin})}
458 """
459 if reset or (self.__bindingRequires is None):
460 if isinstance(self, resolution._Resolvable_mixin) and not (self.isResolved()):
461 raise pyxb.LogicError('Unresolved %s in %s: %s' % (self.__class__.__name__, self._namespaceContext().targetNamespace(), self.name()))
462 self.__bindingRequires = self._bindingRequires_vx(include_lax)
463 return self.__bindingRequires
464
466 """Placeholder for subclass method that identifies the necessary components.
467
468 @note: Override in subclasses.
469
470 @return: The component instances on which this component depends
471 @rtype: C{frozenset}
472 @raise LogicError: A subclass failed to implement this method
473 """
474 raise pyxb.LogicError('%s does not implement _bindingRequires_vx' % (type(self),))
475
477 """Mix-in for managing components defined within this namespace.
478
479 The component set includes not only top-level named components (such as
480 those accessible through category maps), but internal anonymous
481 components, such as those involved in representing the content model of a
482 complex type definition. We need to be able to get a list of these
483 components, sorted in dependency order, so that generated bindings do not
484 attempt to refer to a binding that has not yet been generated."""
485
486
487
488 __components = None
489
491 """CSC extension to reset fields of a Namespace.
492
493 This one handles data related to component association with a
494 namespace."""
495 getattr(super(_NamespaceComponentAssociation_mixin, self), '_reset', lambda *args, **kw: None)()
496 self.__components = set()
497 self.__origins = set()
498 self.__schemaMap = { }
499
507
509 """Replace a component definition in the set of associated components.
510
511 @raise KeyError: C{existing_def} is not in the set of components."""
512
513 self.__components.remove(existing_def)
514 if replacement_def is not None:
515 self.__components.add(replacement_def)
516 return getattr(super(_NamespaceComponentAssociation_mixin, self), '_replaceComponent_csc', lambda *args, **kw: replacement_def)(existing_def, replacement_def)
517
527
536
543
544 __origins = None
545
547 """Return a frozenset of all components, named or unnamed, belonging
548 to this namespace."""
549 return frozenset(self.__components)
550
554
555 from pyxb.namespace import archive
556 from pyxb.namespace.utility import NamespaceInstance
557 from pyxb.namespace.utility import NamespaceForURI
558 from pyxb.namespace.utility import CreateAbsentNamespace
559 from pyxb.namespace.utility import AvailableNamespaces
560 from pyxb.namespace import resolution
561
562 -class Namespace (_NamespaceCategory_mixin, resolution._NamespaceResolution_mixin, _NamespaceComponentAssociation_mixin, archive._NamespaceArchivable_mixin):
563 """Represents an XML namespace (a URI).
564
565 There is at most one L{Namespace} class instance per namespace (URI). The
566 instance also supports associating arbitrary L{maps<NamedObjectMap>} from
567 names to objects, in separate categories. The default categories are
568 configured externally; for example, the
569 L{Schema<pyxb.xmlschema.structures.Schema>} component defines a category
570 for each named component in XMLSchema, and the customizing subclass for
571 WSDL definitions adds categories for the service bindings, messages, etc.
572
573 Namespaces can be written to and loaded from pickled files. See
574 L{NamespaceArchive} for information.
575 """
576
577
578
579 __uri = None
580
581
582
583
584
585
586
587 __absentNamespaceID = 0
588
589
590
591 __boundPrefix = None
592
593
594
595 __prefix = None
596
597
598
599 __Registry = { }
600
601
602 __AbsentNamespaces = set()
603
604
605 __description = None
606
607
608 __isBuiltinNamespace = False
609
610
611 __isUndeclaredNamespace = False
612
613
614 __isLoadedNamespace = False
615
616
617
618 __namespaceArchive = None
619
620
621 __hasBeenArchived = False
622
623
624
625 __builtinModulePath = None
626
627
628
629
630 __bindingConfiguration = None
631
632
633
634
635
636
637 __initialNamespaceContext = None
638
639
640
641 __contextDefaultNamespace = None
642
643
644
645 __contextInScopeNamespaces = None
646
647 @classmethod
649 """If a Namespace instance for the given URI exists, return it; otherwise return None.
650
651 Note; Absent namespaces are not stored in the registry. If you use
652 one (e.g., for a schema with no target namespace), don't lose hold of
653 it."""
654 assert uri is not None
655 return cls.__Registry.get(uri)
656
658 """Pickling support.
659
660 To ensure that unpickled Namespace instances are unique per
661 URI, we ensure that the routine that creates unpickled
662 instances knows what it's supposed to return."""
663 if self.uri() is None:
664 raise pyxb.LogicError('Illegal to serialize absent namespaces')
665 return (self.uri(),)
666
686
687 @classmethod
691
692 - def __init__ (self, uri,
693 description=None,
694 builtin_namespace=None,
695 builtin_module_path=None,
696 is_undeclared_namespace=False,
697 is_loaded_namespace=False,
698 bound_prefix=None,
699 default_namespace=None,
700 in_scope_namespaces=None):
738
743
745 """Return the URI for the namespace represented by this instance.
746
747 If the URI is None, this is an absent namespace, used to hold
748 declarations not associated with a namespace (e.g., from schema with
749 no target namespace)."""
750 return self.__uri
751
759
764
766 """Return True iff this namespace is an absent namespace.
767
768 Absent namespaces have no namespace URI; they exist only to
769 hold components created from schemas with no target
770 namespace."""
771 return self.__uri is None
772
774 """When known to be operating in this namespace, provide the Namespace
775 instance to be used when names are associated with no namespace."""
776 if self.isAbsentNamespace():
777 return self
778 return None
779
780 @classmethod
791
795
797 """Return the standard prefix to be used for this namespace.
798
799 Only a few namespace prefixes are bound to namespaces: xml and xmlns
800 are two. In all other cases, this method should return None. The
801 infrastructure attempts to prevent user creation of Namespace
802 instances that have bound prefixes."""
803 return self.__boundPrefix
804
806 """Return True iff this namespace was defined by the infrastructure.
807
808 That is the case for all namespaces in the Namespace module."""
809 return self.__isBuiltinNamespace
810
812 assert self.__builtinNamespaceVariable is not None
813 return 'pyxb.namespace.%s' % (self.__builtinNamespaceVariable,)
814
823
825 """Return True iff this namespace is always available
826 regardless of whether there is a declaration for it.
827
828 This is the case only for the
829 xml(http://www.w3.org/XML/1998/namespace) and
830 xmlns(http://www.w3.org/2000/xmlns/) namespaces."""
831 return self.__isUndeclaredNamespace
832
834 """Return C{True} iff this namespace was loaded from a namespace archive."""
835 return self.__isLoadedNamespace
836
838 """Return C{True} iff this namespace has been saved to a namespace archive.
839 See also L{isLoadedNamespace}."""
840 return self.__hasBeenArchived
841
847
850
853
855 """Support pickling.
856
857 Well, no, not really. Because namespace instances must be unique, we
858 represent them as their URI, and that's done by __getnewargs__
859 above. All the interesting information is in the ModuleRecords."""
860 return {}
861
864
865 __definedBuiltins = False
875
877 """Attempts to load the named objects held in this namespace.
878
879 The base class implementation looks at the set of available archived
880 namespaces, and if one contains this namespace unserializes its named
881 object maps.
882
883 Sub-classes may choose to look elsewhere, if this version fails or
884 before attempting it.
885
886 There is no guarantee that any particular category of named object has
887 been located when this returns. Caller must check.
888 """
889 for mr in self.moduleRecords():
890 if mr.isLoadable():
891 if mr.isPublic():
892 _log.info('Load %s from %s', mr, mr.archive())
893 try:
894 mr.archive().readNamespaces()
895 except pyxb.NamespaceArchiveError as e:
896 _log.exception("Failure reading namespaces in archive")
897 else:
898 _log.info('Ignoring private module %s in validation', mr)
899 self._activate()
900
901 __didValidation = False
902 __inValidation = False
922
924 """Replace the existing definition with another.
925
926 This is used in a situation where building the component model
927 resulted in a new component instance being created and registered, but
928 for which an existing component is to be preferred. An example is
929 when parsing the schema for XMLSchema itself: the built-in datatype
930 components should be retained instead of the simple type definition
931 components dynamically created from the schema.
932
933 By providing the value C{None} as the replacement definition, this can
934 also be used to remove components.
935
936 @note: Invoking this requires scans of every item in every category
937 map in the namespace.
938
939 @return: C{replacement_def}
940 """
941
942
943 return self._replaceComponent_csc(existing_def, replacement_def)
944
946 """Obtain the namespace context to be used when creating components in this namespace.
947
948 Usually applies only to built-in namespaces, but is also used in the
949 autotests when creating a namespace without a xs:schema element. .
950 Note that we must create the instance dynamically, since the
951 information that goes into it has cross-dependencies that can't be
952 resolved until this module has been completely loaded."""
953
954 if self.__initialNamespaceContext is None:
955 isn = { }
956 if self.__contextInScopeNamespaces is not None:
957 for (k, v) in self.__contextInScopeNamespaces.items():
958 isn[k] = self.__identifyNamespace(v)
959 kw = { 'target_namespace' : self
960 , 'default_namespace' : self.__identifyNamespace(self.__contextDefaultNamespace)
961 , 'in_scope_namespaces' : isn }
962 self.__initialNamespaceContext = resolution.NamespaceContext(None, **kw)
963 return self.__initialNamespaceContext
964
965
967 """Identify the specified namespace, which should be a built-in.
968
969 Normally we can just use a reference to the Namespace module instance,
970 but when creating those instances we sometimes need to refer to ones
971 for which the instance has not yet been created. In that case, we use
972 the name of the instance, and resolve the namespace when we need to
973 create the initial context."""
974 if nsval is None:
975 return self
976 if isinstance(nsval, (str, unicode)):
977 nsval = globals().get(nsval)
978 if isinstance(nsval, Namespace):
979 return nsval
980 raise pyxb.LogicError('Cannot identify namespace from %s' % (nsval,))
981
991
992 from pyxb.namespace.builtin import XMLSchema_instance
993 from pyxb.namespace.builtin import XMLNamespaces
994 from pyxb.namespace.builtin import XMLSchema
995 from pyxb.namespace.builtin import XHTML
996 from pyxb.namespace.builtin import XML
997 from pyxb.namespace.builtin import XMLSchema_hfp
998 from pyxb.namespace.builtin import BuiltInObjectUID
999
1000 resolution.NamespaceContext._AddTargetNamespaceAttribute(XMLSchema.createExpandedName('schema'), ExpandedName('targetNamespace'))
1001
1002
1003
1004
1005