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__)
29
30 @pyxb.utils.utility.BackfillComparisons
32
33 """Represent an U{expanded name
34 <http://www.w3.org/TR/REC-xml-names/#dt-expname>}, which pairs a
35 namespace with a local name.
36
37 Because a large number of local elements, and most attributes, have no
38 namespace associated with them, this is optimized for representing names
39 with an absent namespace. The hash and equality test methods are set so
40 that a plain string is equivalent to a tuple of C{None} and that string.
41
42 Note that absent namespaces can be represented in two ways: with a
43 namespace of C{None} (the name "has no namespace"), and with a namespace
44 that is an L{absent namespace <Namespace.CreateAbsentNamespace>} (the name
45 "has an absent namespace"). Hash code calculations are done so that the
46 two alternatives produce the same hash; however, comparison is done so
47 that the two are distinguished. The latter is the intended behavior; the
48 former should not be counted upon.
49
50 This class allows direct lookup of the named object within a category by
51 using the category name as an accessor function. That is, if the
52 namespace of the expanded name C{en} has a category 'typeDefinition', then
53 the following two expressions are equivalent::
54
55 en.typeDefinition()
56 en.namespace().categoryMap('typeDefinition').get(en.localName())
57
58 This class descends from C{tuple} so that its values can be used as
59 dictionary keys without concern for pointer equivalence.
60 """
62 """The L{Namespace} part of the expanded name."""
63 return self.__namespace
64 __namespace = None
65
67 """Return the URI of the namespace, or C{None} if the namespace is absent."""
68 return self.__namespaceURI
69 __namespaceURI = None
70
72 """The local part of the expanded name."""
73 return self.__localName
74 __localName = None
75
76
77 __expandedName = None
78
82
84 """Return a tuple consisting of the namespace URI and the local name.
85
86 This presents the expanded name as base Python types for persistent
87 storage. Be aware, though, that it will lose the association of the
88 name with an absent namespace, if that matters to you."""
89 return ( self.__namespaceURI, self.__localName )
90
91
101
103 """Return a new expanded name in the namespace of this name.
104
105 @param local_name: The local name portion of an expanded name.
106 @return: An instance of L{ExpandedName}.
107 """
108 return ExpandedName(self.namespace(), local_name)
109
111 """Return the input name, except if the input name has no namespace,
112 return a name that uses the namespace from this name with the local
113 name from the input name.
114
115 Use this when the XML document has an unqualified name and we're
116 processing using an absent default namespace.
117
118 @warning: Be careful when using a global name to adopt a name from a
119 local element: if the local element (with no namespace) has the same
120 localName as but is different from the global element (with a
121 namespace), this will improperly provide a namespace when one should
122 not be present. See the comments in
123 L{pyxb.binding.basis.element.elementForName}.
124 """
125
126 if not isinstance(name, ExpandedName):
127 name = ExpandedName(name)
128 if name.namespace() is None:
129 name = self.createName(name.localName())
130 return name
131
133 """Create an expanded name.
134
135 Expected argument patterns are:
136
137 - ( C{str} ) : the local name in an absent namespace
138 - ( L{ExpandedName} ) : a copy of the given expanded name
139 - ( C{xml.dom.Node} ) : The name extracted from node.namespaceURI and node.localName
140 - ( C{str}, C{str} ) : the namespace URI and the local name
141 - ( L{Namespace}, C{str} ) : the namespace and the local name
142 - ( L{ExpandedName}, C{str}) : the namespace from the expanded name, and the local name
143
144 Wherever C{str} occurs C{unicode} is also permitted.
145
146 @keyword fallback_namespace: Optional Namespace instance to use if the
147 namespace would otherwise be None. This is only used if it is an
148 absent namespace.
149
150 """
151 fallback_namespace = kw.get('fallback_namespace')
152 if 0 == len(args):
153 raise pyxb.LogicError('Too few arguments to ExpandedName constructor')
154 if 2 < len(args):
155 raise pyxb.LogicError('Too many arguments to ExpandedName constructor')
156 if 2 == len(args):
157
158 ( ns, ln ) = args
159 else:
160
161 assert 1 == len(args)
162 ln = args[0]
163 ns = None
164 if isinstance(ln, basestring):
165 pass
166 elif isinstance(ln, tuple) and (2 == len(ln)):
167 (ns, ln) = ln
168 elif isinstance(ln, ExpandedName):
169 ns = ln.namespace()
170 ln = ln.localName()
171 elif isinstance(ln, xml.dom.Node):
172 if not(ln.nodeType in (xml.dom.Node.ELEMENT_NODE, xml.dom.Node.ATTRIBUTE_NODE)):
173 raise pyxb.LogicError('Cannot create expanded name from non-element DOM node %s' % (ln.nodeType,))
174 ns = ln.namespaceURI
175 ln = ln.localName
176 else:
177 raise pyxb.LogicError('Unrecognized argument type %s' % (type(ln),))
178 if (ns is None) and (fallback_namespace is not None):
179 if fallback_namespace.isAbsentNamespace():
180 ns = fallback_namespace
181 if isinstance(ns, (str, unicode)):
182 ns = NamespaceForURI(ns, create_if_missing=True)
183 if isinstance(ns, ExpandedName):
184 ns = ns.namespace()
185 if (ns is not None) and not isinstance(ns, Namespace):
186 raise pyxb.LogicError('ExpandedName must include a valid (perhaps absent) namespace, or None.')
187 self.__namespace = ns
188 if self.__namespace is not None:
189 self.__namespaceURI = self.__namespace.uri()
190 self.__localName = ln
191 assert self.__localName is not None
192 self.__expandedName = ( self.__namespace, self.__localName )
193 self.__uriTuple = ( self.__namespaceURI, self.__localName )
194
195
201
207
209 if isinstance(other, (str, unicode)):
210 other = ( None, other )
211 if not isinstance(other, tuple):
212 other = other.__uriTuple
213 if isinstance(other[0], Namespace):
214 other = ( other[0].uri(), other[1] )
215 return other
216
221
226
236
240
242 """An extended dictionary intended to assist with QName resolution.
243
244 These dictionaries have an attribute that identifies a category of named
245 objects within a Namespace; the specifications for various documents
246 require that certain groups of objects must be unique, while uniqueness is
247 not required between groups. The dictionary also retains a pointer to the
248 Namespace instance for which it holds objects."""
250 """The namespace to which the object map belongs."""
251 return self.__namespace
252 __namespace = None
253
255 """The category of objects (e.g., typeDefinition, elementDeclaration)."""
256 return self.__category
257 __category = None
258
259 - def __init__ (self, category, namespace, *args, **kw):
263
265 """Mix-in that aggregates those aspects of XMLNamespaces that hold
266 references to categories of named objects.
267
268 Arbitrary groups of named objects, each requiring unique names within
269 themselves, can be saved. Unless configured otherwise, the Namespace
270 instance is extended with accessors that provide direct access to
271 individual category maps. The name of the method is the category name
272 with a suffix of "s"; e.g., if a category "typeDefinition" exists, it can
273 be accessed from the namespace using the syntax C{ns.typeDefinitions()}.
274
275 Note that the returned value from the accessor is a live reference to
276 the category map; changes made to the map are reflected in the
277 namespace.
278 """
279
280
281
282 __categoryMap = None
283
285 """CSC extension to reset fields of a Namespace.
286
287 This one handles category-related data."""
288 getattr(super(_NamespaceCategory_mixin, self), '_reset', lambda *args, **kw: None)()
289 self.__categoryMap = { }
290
292 """The list of individual categories held in this namespace."""
293 return list(self.__categoryMap.keys())
294
296 """Return the whole map from categories to named objects."""
297 return self.__categoryMap
298
305
307 """Define public methods on the Namespace which provide access to
308 individual NamedObjectMaps based on their category.
309
310 """
311 for category in self.categories():
312 accessor_name = category + 's'
313 setattr(self, accessor_name, lambda _map=self.categoryMap(category): _map)
314
331
333 """Allow access to the named_object by looking up the local_name in
334 the given category.
335
336 Raises pyxb.NamespaceUniquenessError if an object with the same name
337 already exists in the category."""
338 name_map = self.categoryMap(category)
339 old_object = name_map.get(local_name)
340 if (old_object is not None) and (old_object != named_object):
341 raise pyxb.NamespaceUniquenessError(self, '%s: name %s used for multiple values in %s' % (self, local_name, category))
342 name_map[local_name] = named_object
343 return named_object
344
346 """Replace the referenced object in the category.
347
348 The new object will be added only if the old_object matches the
349 current entry for local_name in the category."""
350 name_map = self.categoryMap(category)
351 if old_object == name_map.get(local_name):
352 name_map[local_name] = new_object
353 return name_map[local_name]
354
356 """Replace a component definition where present in the category maps.
357
358 @note: This is a high-cost operation, as every item in every category
359 map must be examined to see whether its value field matches
360 C{existing_def}."""
361 for (cat, registry) in self.__categoryMap.iteritems():
362 for (k, v) in registry.items():
363 if v == existing_def:
364 del registry[k]
365 if replacement_def is not None:
366 registry[k] = replacement_def
367 return getattr(super(_NamespaceCategory_mixin, self), '_replaceComponent_csc', lambda *args, **kw: replacement_def)(existing_def, replacement_def)
368
369
370
371
372
373
384
390
392 """Add the named objects from the given map into the set held by this namespace.
393 It is an error to name something which is already present."""
394 self.configureCategories(category_map.iterkeys())
395 for category in category_map.iterkeys():
396 current_map = self.categoryMap(category)
397 new_map = category_map[category]
398 for (local_name, component) in new_map.iteritems():
399 existing_component = current_map.get(local_name)
400 if existing_component is None:
401 current_map[local_name] = component
402 elif existing_component._allowUpdateFromOther(component):
403 existing_component._updateFromOther(component)
404 else:
405 raise pyxb.NamespaceError(self, 'Load attempted to override %s %s in %s' % (category, local_name, self.uri()))
406 self.__defineCategoryAccessors()
407
409 """Return C{True} iff schema components have been associated with this namespace.
410
411 This only checks whether the corresponding categories have been added,
412 not whether there are any entries in those categories. It is useful
413 for identifying namespaces that were incorporated through a
414 declaration but never actually referenced."""
415 return 'typeDefinition' in self.__categoryMap
416
435
437 """Mix-in for components that can depend on other components."""
438
439 __PrivateTransient = set()
440
441
442 __bindingRequires = None
443 __PrivateTransient.add('bindingRequires')
444
446 """CSC extension to reset fields of a component. This one clears
447 dependency-related data, since the clone will have to revise its
448 dependencies.
449 @rtype: C{None}"""
450 getattr(super(_ComponentDependency_mixin, self), '_resetClone_csc', lambda *_args, **_kw: None)(**kw)
451 self.__bindingRequires = None
452
454 """Return a set of components upon whose bindings this component's
455 bindings depend.
456
457 For example, bindings that are extensions or restrictions depend on
458 their base types. Complex type definition bindings require that the
459 types of their attribute declarations be available at the class
460 definition, and the types of their element declarations in the
461 postscript.
462
463 @keyword include_lax: if C{False} (default), only the requirements of
464 the class itself are returned. If C{True}, all requirements are
465 returned.
466 @rtype: C{set(L{pyxb.xmlschema.structures._SchemaComponent_mixin})}
467 """
468 if reset or (self.__bindingRequires is None):
469 if isinstance(self, resolution._Resolvable_mixin) and not (self.isResolved()):
470 raise pyxb.LogicError('Unresolved %s in %s: %s' % (self.__class__.__name__, self._namespaceContext().targetNamespace(), self.name()))
471 self.__bindingRequires = self._bindingRequires_vx(include_lax)
472 return self.__bindingRequires
473
475 """Placeholder for subclass method that identifies the necessary components.
476
477 @note: Override in subclasses.
478
479 @return: The component instances on which this component depends
480 @rtype: C{frozenset}
481 @raise LogicError: A subclass failed to implement this method
482 """
483 raise pyxb.LogicError('%s does not implement _bindingRequires_vx' % (type(self),))
484
486 """Mix-in for managing components defined within this namespace.
487
488 The component set includes not only top-level named components (such as
489 those accessible through category maps), but internal anonymous
490 components, such as those involved in representing the content model of a
491 complex type definition. We need to be able to get a list of these
492 components, sorted in dependency order, so that generated bindings do not
493 attempt to refer to a binding that has not yet been generated."""
494
495
496
497 __components = None
498
500 """CSC extension to reset fields of a Namespace.
501
502 This one handles data related to component association with a
503 namespace."""
504 getattr(super(_NamespaceComponentAssociation_mixin, self), '_reset', lambda *args, **kw: None)()
505 self.__components = set()
506 self.__origins = set()
507 self.__schemaMap = { }
508
516
518 """Replace a component definition in the set of associated components.
519
520 @raise KeyError: C{existing_def} is not in the set of components."""
521
522 self.__components.remove(existing_def)
523 if replacement_def is not None:
524 self.__components.add(replacement_def)
525 return getattr(super(_NamespaceComponentAssociation_mixin, self), '_replaceComponent_csc', lambda *args, **kw: replacement_def)(existing_def, replacement_def)
526
536
545
552
553 __origins = None
554
556 """Return a frozenset of all components, named or unnamed, belonging
557 to this namespace."""
558 return frozenset(self.__components)
559
563
564 from pyxb.namespace import archive
565 from pyxb.namespace.utility import NamespaceInstance
566 from pyxb.namespace.utility import NamespaceForURI
567 from pyxb.namespace.utility import CreateAbsentNamespace
568 from pyxb.namespace.utility import AvailableNamespaces
569 from pyxb.namespace import resolution
570
571 -class Namespace (_NamespaceCategory_mixin, resolution._NamespaceResolution_mixin, _NamespaceComponentAssociation_mixin, archive._NamespaceArchivable_mixin):
572 """Represents an XML namespace (a URI).
573
574 There is at most one L{Namespace} class instance per namespace (URI). The
575 instance also supports associating arbitrary L{maps<NamedObjectMap>} from
576 names to objects, in separate categories. The default categories are
577 configured externally; for example, the
578 L{Schema<pyxb.xmlschema.structures.Schema>} component defines a category
579 for each named component in XMLSchema, and the customizing subclass for
580 WSDL definitions adds categories for the service bindings, messages, etc.
581
582 Namespaces can be written to and loaded from pickled files. See
583 L{NamespaceArchive} for information.
584 """
585
586
587
588 __uri = None
589
590
591
592
593
594
595
596 __absentNamespaceID = 0
597
598
599
600 __boundPrefix = None
601
602
603
604 __prefix = None
605
606
607
608 __Registry = { }
609
610
611 __AbsentNamespaces = set()
612
613
614 __description = None
615
616
617 __isBuiltinNamespace = False
618
619
620 __isUndeclaredNamespace = False
621
622
623 __isLoadedNamespace = False
624
625
626
627 __namespaceArchive = None
628
629
630 __hasBeenArchived = False
631
632
633
634 __builtinModulePath = None
635
636
637
638
639 __bindingConfiguration = None
640
641
642
643
644
645
646 __initialNamespaceContext = None
647
648
649
650 __contextDefaultNamespace = None
651
652
653
654 __contextInScopeNamespaces = None
655
656 @classmethod
658 """If a Namespace instance for the given URI exists, return it; otherwise return None.
659
660 Note; Absent namespaces are not stored in the registry. If you use
661 one (e.g., for a schema with no target namespace), don't lose hold of
662 it."""
663 assert uri is not None
664 return cls.__Registry.get(uri)
665
667 """Pickling support.
668
669 To ensure that unpickled Namespace instances are unique per
670 URI, we ensure that the routine that creates unpickled
671 instances knows what it's supposed to return."""
672 if self.uri() is None:
673 raise pyxb.LogicError('Illegal to serialize absent namespaces')
674 return (self.uri(),)
675
695
696 @classmethod
700
701 - def __init__ (self, uri,
702 description=None,
703 builtin_namespace=None,
704 builtin_module_path=None,
705 is_undeclared_namespace=False,
706 is_loaded_namespace=False,
707 bound_prefix=None,
708 default_namespace=None,
709 in_scope_namespaces=None):
747
752
754 """Return the URI for the namespace represented by this instance.
755
756 If the URI is None, this is an absent namespace, used to hold
757 declarations not associated with a namespace (e.g., from schema with
758 no target namespace)."""
759 return self.__uri
760
768
773
775 """Return True iff this namespace is an absent namespace.
776
777 Absent namespaces have no namespace URI; they exist only to
778 hold components created from schemas with no target
779 namespace."""
780 return self.__uri is None
781
783 """When known to be operating in this namespace, provide the Namespace
784 instance to be used when names are associated with no namespace."""
785 if self.isAbsentNamespace():
786 return self
787 return None
788
789 @classmethod
800
804
806 """Return the standard prefix to be used for this namespace.
807
808 Only a few namespace prefixes are bound to namespaces: xml and xmlns
809 are two. In all other cases, this method should return None. The
810 infrastructure attempts to prevent user creation of Namespace
811 instances that have bound prefixes."""
812 return self.__boundPrefix
813
815 """Return True iff this namespace was defined by the infrastructure.
816
817 That is the case for all namespaces in the Namespace module."""
818 return self.__isBuiltinNamespace
819
821 assert self.__builtinNamespaceVariable is not None
822 return 'pyxb.namespace.%s' % (self.__builtinNamespaceVariable,)
823
832
834 """Return True iff this namespace is always available
835 regardless of whether there is a declaration for it.
836
837 This is the case only for the
838 xml(http://www.w3.org/XML/1998/namespace) and
839 xmlns(http://www.w3.org/2000/xmlns/) namespaces."""
840 return self.__isUndeclaredNamespace
841
843 """Return C{True} iff this namespace was loaded from a namespace archive."""
844 return self.__isLoadedNamespace
845
847 """Return C{True} iff this namespace has been saved to a namespace archive.
848 See also L{isLoadedNamespace}."""
849 return self.__hasBeenArchived
850
856
859
862
864 """Support pickling.
865
866 Well, no, not really. Because namespace instances must be unique, we
867 represent them as their URI, and that's done by __getnewargs__
868 above. All the interesting information is in the ModuleRecords."""
869 return {}
870
873
874 __definedBuiltins = False
884
886 """Attempts to load the named objects held in this namespace.
887
888 The base class implementation looks at the set of available archived
889 namespaces, and if one contains this namespace unserializes its named
890 object maps.
891
892 Sub-classes may choose to look elsewhere, if this version fails or
893 before attempting it.
894
895 There is no guarantee that any particular category of named object has
896 been located when this returns. Caller must check.
897 """
898 for mr in self.moduleRecords():
899 if mr.isLoadable():
900 if mr.isPublic():
901 _log.info('Load %s from %s', mr, mr.archive())
902 try:
903 mr.archive().readNamespaces()
904 except pyxb.NamespaceArchiveError:
905 _log.exception("Failure reading namespaces in archive")
906 else:
907 _log.info('Ignoring private module %s in validation', mr)
908 self._activate()
909
910 __didValidation = False
911 __inValidation = False
931
933 """Replace the existing definition with another.
934
935 This is used in a situation where building the component model
936 resulted in a new component instance being created and registered, but
937 for which an existing component is to be preferred. An example is
938 when parsing the schema for XMLSchema itself: the built-in datatype
939 components should be retained instead of the simple type definition
940 components dynamically created from the schema.
941
942 By providing the value C{None} as the replacement definition, this can
943 also be used to remove components.
944
945 @note: Invoking this requires scans of every item in every category
946 map in the namespace.
947
948 @return: C{replacement_def}
949 """
950
951
952 return self._replaceComponent_csc(existing_def, replacement_def)
953
955 """Obtain the namespace context to be used when creating components in this namespace.
956
957 Usually applies only to built-in namespaces, but is also used in the
958 autotests when creating a namespace without a xs:schema element. .
959 Note that we must create the instance dynamically, since the
960 information that goes into it has cross-dependencies that can't be
961 resolved until this module has been completely loaded."""
962
963 if self.__initialNamespaceContext is None:
964 isn = { }
965 if self.__contextInScopeNamespaces is not None:
966 for (k, v) in self.__contextInScopeNamespaces.iteritems():
967 isn[k] = self.__identifyNamespace(v)
968 kw = { 'target_namespace' : self
969 , 'default_namespace' : self.__identifyNamespace(self.__contextDefaultNamespace)
970 , 'in_scope_namespaces' : isn }
971 self.__initialNamespaceContext = resolution.NamespaceContext(None, **kw)
972 return self.__initialNamespaceContext
973
974
976 """Identify the specified namespace, which should be a built-in.
977
978 Normally we can just use a reference to the Namespace module instance,
979 but when creating those instances we sometimes need to refer to ones
980 for which the instance has not yet been created. In that case, we use
981 the name of the instance, and resolve the namespace when we need to
982 create the initial context."""
983 if nsval is None:
984 return self
985 if isinstance(nsval, (str, unicode)):
986 nsval = globals().get(nsval)
987 if isinstance(nsval, Namespace):
988 return nsval
989 raise pyxb.LogicError('Cannot identify namespace from %s' % (nsval,))
990
1000
1001 from pyxb.namespace.builtin import XMLSchema_instance
1002 from pyxb.namespace.builtin import XMLNamespaces
1003 from pyxb.namespace.builtin import XMLSchema
1004 from pyxb.namespace.builtin import XHTML
1005 from pyxb.namespace.builtin import XML
1006 from pyxb.namespace.builtin import XMLSchema_hfp
1007 from pyxb.namespace.builtin import BuiltInObjectUID
1008
1009 resolution.NamespaceContext._AddTargetNamespaceAttribute(XMLSchema.createExpandedName('schema'), ExpandedName('targetNamespace'))
1010
1011
1012
1013
1014