1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 """The really ugly code that generates the Python bindings. This
16 whole thing is going to be refactored once customized generation makes
17 it to the top of the task queue."""
18
19 import pyxb
20 import pyxb.xmlschema as xs
21 import StringIO
22 import datetime
23 import urlparse
24 import errno
25
26 from pyxb.utils import utility
27 from pyxb.utils import templates
28 from pyxb.utils import domutils
29 import basis
30 import content
31 import datatypes
32 import facets
33
34 import types
35 import sys
36 import traceback
37 import xml.dom
38 import os.path
39 import StringIO
40
41
42
43 UniqueInBinding = set([ 'pyxb', 'sys', 'Namespace', 'ModuleRecord', 'CreateFromDocument', 'CreateFromDOM' ])
53
55 """Base class for something that requires fairly complex activity
56 in order to generate its literal value."""
57
58
59
60 __ownerClass = None
61
62
63 __literal = None
64
68
72
75
80
96
98 __wildcard = None
99
101 self.__wildcard = wildcard
102 super(ReferenceWildcard, self).__init__(**kw)
103
104 template_map = { }
105 template_map['Wildcard'] = 'pyxb.binding.content.Wildcard'
106 if (xs.structures.Wildcard.NC_any == wildcard.namespaceConstraint()):
107 template_map['nc'] = templates.replaceInText('%{Wildcard}.NC_any', **template_map)
108 elif isinstance(wildcard.namespaceConstraint(), (set, frozenset)):
109 namespaces = []
110 for ns in wildcard.namespaceConstraint():
111 if ns is None:
112 namespaces.append(None)
113 else:
114 namespaces.append(ns.uri())
115 template_map['nc'] = 'set([%s])' % (",".join( [ repr(_ns) for _ns in namespaces ]))
116 else:
117 assert isinstance(wildcard.namespaceConstraint(), tuple)
118 ns = wildcard.namespaceConstraint()[1]
119 if ns is not None:
120 ns = ns.uri()
121 template_map['nc'] = templates.replaceInText('(%{Wildcard}.NC_not, %{namespace})', namespace=repr(ns), **template_map)
122 template_map['pc'] = wildcard.processContents()
123 self.setLiteral(templates.replaceInText('%{Wildcard}(process_contents=%{Wildcard}.PC_%{pc}, namespace_constraint=%{nc})', **template_map))
124
134
143
150
158
160 enumerationElement = None
161
163
164
165
166
167
168
169
170
171 value = kw.get('enum_value', None)
172 assert (value is None) or isinstance(value, facets._Enumeration_mixin)
173
174
175
176 facet_instance = kw.get('facet_instance', None)
177 if facet_instance is None:
178 assert isinstance(value, facets._Enumeration_mixin)
179 facet_instance = value._CF_enumeration
180 assert isinstance(facet_instance, facets.CF_enumeration)
181
182
183
184 self.enumerationElement = kw.get('enumeration_element', None)
185 if self.enumerationElement is None:
186 assert value is not None
187 self.enumerationElement = facet_instance.elementForValue(value)
188 assert isinstance(self.enumerationElement, facets._EnumerationElement)
189 assert self.enumerationElement.tag() is not None
190
191
192
193 kw.setdefault('type_definition', facet_instance.valueDatatype())
194
195 super(ReferenceEnumerationMember, self).__init__(**kw)
196
197 self.setLiteral(self._addTypePrefix(self.enumerationElement.tag(), **kw))
198
200
201 if isinstance(value, types.DictionaryType):
202 return ', '.join([ '%s=%s' % (k, pythonLiteral(v, **kw)) for (k, v) in value.items() ])
203
204
205 if isinstance(value, types.ListType):
206 return [ pythonLiteral(_v, **kw) for _v in value ]
207
208
209 if isinstance(value, pyxb.namespace.ExpandedName):
210 return pythonLiteral(ReferenceExpandedName(expanded_name=value, **kw))
211
212
213 if isinstance(value, (types.TupleType, set)):
214 return type(value)(pythonLiteral(list(value), **kw))
215
216
217
218 if isinstance(value, facets._Enumeration_mixin):
219 return pythonLiteral(ReferenceEnumerationMember(enum_value=value, **kw))
220
221
222
223
224 if isinstance(value, basis.simpleTypeDefinition):
225 return PrefixModule(value, value.pythonLiteral())
226
227 if isinstance(value, pyxb.namespace.Namespace):
228 return pythonLiteral(ReferenceNamespace(namespace=value, **kw))
229
230 if isinstance(value, type):
231 if issubclass(value, basis.simpleTypeDefinition):
232 return PrefixModule(value)
233 if issubclass(value, facets.Facet):
234 return PrefixModule(value)
235
236
237 if isinstance(value, types.StringTypes):
238 return utility.QuotedEscaped(value,)
239
240 if isinstance(value, facets.Facet):
241 return pythonLiteral(ReferenceFacet(facet=value, **kw))
242
243
244 if isinstance(value, facets._PatternElement):
245 return pythonLiteral(value.pattern)
246
247
248 if isinstance(value, facets._EnumerationElement):
249 return pythonLiteral(value.value())
250
251
252 if isinstance(value, xs.structures.Particle):
253 return pythonLiteral(ReferenceParticle(value, **kw))
254
255
256 if isinstance(value, xs.structures.Wildcard):
257 return pythonLiteral(ReferenceWildcard(value, **kw))
258
259
260 if isinstance(value, xs.structures._SchemaComponent_mixin):
261 return pythonLiteral(ReferenceSchemaComponent(value, **kw))
262
263
264 if isinstance(value, ReferenceLiteral):
265 return value.asLiteral()
266
267
268 if isinstance(value, pyxb.namespace.Namespace):
269 return repr(value.uri())
270
271
272 if isinstance(value, (types.NoneType, types.BooleanType, types.FloatType, types.IntType, types.LongType)):
273 return repr(value)
274
275 raise Exception('Unexpected literal type %s' % (type(value),))
276 print 'Unexpected literal type %s' % (type(value),)
277 return str(value)
278
279
280 -def GenerateContentTerm (ctd, term, binding_module, **kw):
281 lines = []
282 padding = ' '
283 separator = ",\n%s" % (padding,)
284 template_map = { 'ctd' : binding_module.literal(ctd, **kw) }
285 if isinstance(term, xs.structures.Wildcard):
286 term_val = binding_module.literal(term, **kw)
287 elif isinstance(term, xs.structures.ElementDeclaration):
288 term_val = templates.replaceInText('%{ctd}._UseForTag(%{field_tag})', field_tag=binding_module.literal(term.expandedName(), **kw), **template_map)
289 else:
290 gm_id = utility.PrepareIdentifier('GroupModel', binding_module.uniqueInClass(ctd), protected=True)
291 assert isinstance(term, xs.structures.ModelGroup)
292 if (term.C_ALL == term.compositor()):
293 group_val = 'All'
294 elif (term.C_CHOICE == term.compositor()):
295 group_val = 'Choice'
296 else:
297 assert term.C_SEQUENCE == term.compositor()
298 group_val = 'Sequence'
299 pvalues = []
300 for p in term.particles():
301 (value, plines) = GenerateContentParticle(ctd, p, binding_module, **kw)
302 if plines:
303 lines.extend(plines)
304 pvalues.append(value)
305 group_val = "pyxb.binding.content.Group%s(\n" % (group_val,) + padding + separator.join(pvalues) + "\n" + padding + ")"
306 template_map['gm_id'] = gm_id
307 lines.append(templates.replaceInText('%{ctd}.%{gm_id} = %{group_val}', group_val=group_val, **template_map))
308 term_val = templates.replaceInText('%{ctd}.%{gm_id}', **template_map)
309 return (term_val, lines)
310
311 -def GenerateContentParticle (ctd, particle, binding_module, **kw):
312 template_map = { }
313 template_map['ctd'] = binding_module.literal(ctd, **kw)
314 template_map['min_occurs'] = repr(particle.minOccurs())
315 template_map['max_occurs'] = repr(particle.maxOccurs())
316 (term_val, lines) = GenerateContentTerm(ctd, particle.term(), binding_module, **kw)
317 particle_val = templates.replaceInText('pyxb.binding.content.ParticleModel(%{term_val}, min_occurs=%{min_occurs}, max_occurs=%{max_occurs})', term_val=term_val, **template_map)
318 return (particle_val, lines)
319
339
341 binding_module = kw['binding_module']
342 outf = binding_module.bindingIO()
343 facet_instances = []
344 gen_enum_tag = _useEnumerationTags(td)
345 for (fc, fi) in td.facets().items():
346
347
348 if (fi is None) and (fc in td.baseTypeDefinition().facets()):
349
350
351 continue
352 if (fi is not None) and (fi.ownerTypeDefinition() != td):
353
354
355 continue
356 argset = { }
357 is_collection = issubclass(fc, facets._CollectionFacet_mixin)
358 if issubclass(fc, facets._LateDatatype_mixin):
359 vdt = td
360 if fc.LateDatatypeBindsSuperclass():
361 vdt = vdt.baseTypeDefinition()
362 argset['value_datatype'] = vdt
363 if fi is not None:
364 if not is_collection:
365 argset['value'] = fi.value()
366 if isinstance(fi, facets.CF_enumeration):
367 argset['enum_prefix'] = fi.enumPrefix()
368 facet_var = ReferenceFacetMember(type_definition=td, facet_class=fc, **kw)
369 outf.write("%s = %s(%s)\n" % binding_module.literal( (facet_var, fc, argset ), **kw))
370 facet_instances.append(binding_module.literal(facet_var, **kw))
371 if (fi is not None) and is_collection:
372 for i in fi.items():
373 if isinstance(i, facets._EnumerationElement):
374 enum_config = '%s.addEnumeration(unicode_value=%s, tag=%s)' % binding_module.literal( ( facet_var, i.unicodeValue(), i.tag() ), **kw)
375 if gen_enum_tag and (i.tag() is not None):
376 enum_member = ReferenceEnumerationMember(type_definition=td, facet_instance=fi, enumeration_element=i, **kw)
377 outf.write("%s = %s\n" % (binding_module.literal(enum_member, **kw), enum_config))
378 if fi.enumPrefix() is not None:
379 outf.write("%s_%s = %s\n" % (fi.enumPrefix(), i.tag(), binding_module.literal(enum_member, **kw)))
380 else:
381 outf.write("%s\n" % (enum_config,))
382 if isinstance(i, facets._PatternElement):
383 outf.write("%s.addPattern(pattern=%s)\n" % binding_module.literal( (facet_var, i.pattern ), **kw))
384 if gen_enum_tag and (xs.structures.SimpleTypeDefinition.VARIETY_union == td.variety()):
385
386
387
388 fi = td.facets().get(facets.CF_enumeration)
389 if fi is None:
390
391 for mtd in td.memberTypeDefinitions():
392 if not _useEnumerationTags(mtd):
393 continue
394 fi = mtd.facets().get(facets.CF_enumeration)
395 if fi is None:
396 continue
397 for i in fi.items():
398 assert isinstance(i, facets._EnumerationElement)
399 etd = i.enumeration().ownerTypeDefinition()
400 enum_member = ReferenceEnumerationMember(type_definition=td, facet_instance=fi, enumeration_element=i, **kw)
401 outf.write("%-50s%s\n" % ('%s = %s' % binding_module.literal( (enum_member, i.unicodeValue()) ),
402 '# originally %s.%s' % (binding_module.literal(etd), i.tag())))
403 if 2 <= len(facet_instances):
404 map_args = ",\n ".join(facet_instances)
405 else:
406 map_args = ','.join(facet_instances)
407 outf.write("%s._InitializeFacetMap(%s)\n" % (binding_module.literal(td, **kw), map_args))
408
410
411 binding_module = generator.moduleForComponent(std)
412 outf = binding_module.bindingIO()
413
414 class_keywords = frozenset(basis.simpleTypeDefinition._ReservedSymbols)
415 class_unique = set()
416
417 kw = { }
418 kw['binding_module'] = binding_module
419 kw['class_keywords'] = class_keywords
420 kw['class_unique'] = class_unique
421
422 parent_classes = [ binding_module.literal(std.baseTypeDefinition(), **kw) ]
423 enum_facet = std.facets().get(facets.CF_enumeration, None)
424 if (enum_facet is not None) and (enum_facet.ownerTypeDefinition() == std):
425 parent_classes.append('pyxb.binding.basis.enumeration_mixin')
426
427 template_map = { }
428 binding_name = template_map['std'] = binding_module.literal(std, **kw)
429 if (std.expandedName() is not None) and (std.expandedName().localName() != binding_name):
430 print 'Simple type %s renamed to %s' % (std.expandedName(), binding_name)
431
432 template_map['superclasses'] = ''
433 if 0 < len(parent_classes):
434 template_map['superclasses'] = ', '.join(parent_classes)
435 template_map['expanded_name'] = binding_module.literal(std.expandedName(), **kw)
436 template_map['namespaceReference'] = binding_module.literal(std.bindingNamespace(), **kw)
437 if std.annotation() is not None:
438 template_map['documentation'] = std.annotation().asDocString()
439 template_map['documentation_expr'] = binding_module.literal(std.annotation().text())
440 else:
441 template_map['documentation'] = ''
442 template_map['documentation_expr'] = binding_module.literal(None)
443
444
445
446 common_template = '''
447 """%{documentation}"""
448
449 _ExpandedName = %{expanded_name}
450 _Documentation = %{documentation_expr}
451 '''
452 if xs.structures.SimpleTypeDefinition.VARIETY_absent == std.variety():
453 template = '''
454 # The ur SimpleTypeDefinition
455 class %{std} (%{superclasses}):
456 ''' + common_template
457 if not template_map['documentation']:
458 template_map['documentation'] = 'The ur simple type.'
459 elif xs.structures.SimpleTypeDefinition.VARIETY_atomic == std.variety():
460 template = '''
461 # Atomic SimpleTypeDefinition
462 class %{std} (%{superclasses}):
463 ''' + common_template
464 if not template_map['documentation']:
465 template_map['documentation'] = 'An atomic simple type.'
466 elif xs.structures.SimpleTypeDefinition.VARIETY_list == std.variety():
467 template = '''
468 # List SimpleTypeDefinition
469 # superclasses %{superclasses}
470 class %{std} (pyxb.binding.basis.STD_list):
471 ''' + common_template + '''
472 _ItemType = %{itemtype}
473 '''
474 template_map['itemtype'] = binding_module.literal(std.itemTypeDefinition(), **kw)
475 if not template_map['documentation']:
476 template_map['documentation'] = templates.replaceInText('Simple type that is a list of %{itemtype}.', **template_map)
477 elif xs.structures.SimpleTypeDefinition.VARIETY_union == std.variety():
478 template = '''
479 # Union SimpleTypeDefinition
480 # superclasses %{superclasses}
481 class %{std} (pyxb.binding.basis.STD_union):
482 ''' + common_template + '''
483 _MemberTypes = ( %{membertypes}, )
484 '''
485 template_map['membertypes'] = ", ".join( [ binding_module.literal(_mt, **kw) for _mt in std.memberTypeDefinitions() ])
486 if not template_map['documentation']:
487 template_map['documentation'] = templates.replaceInText('Simple type that is a union of %{membertypes}.', **template_map)
488 else:
489 raise pyxb.LogicError("Unhandled STD variety")
490
491 outf.write(templates.replaceInText(template, **template_map))
492
493 generate_facets = False
494 if generate_facets:
495
496 if std.isBuiltin():
497 GenerateFacets(std, generator, **kw)
498 else:
499 GenerateFacets(std, generator, **kw)
500
501 if std.name() is not None:
502 outf.write(templates.replaceInText("%{namespaceReference}.addCategoryObject('typeBinding', %{localName}, %{std})\n",
503 localName=binding_module.literal(std.name(), **kw), **template_map))
504
506 template_map = { }
507 template_map['name'] = unicode(ed.expandedName())
508 template_map['namespaceReference'] = binding_module.literal(ed.bindingNamespace(), **kw)
509 if (ed.SCOPE_global == ed.scope()):
510 binding_name = template_map['class'] = binding_module.literal(ed, **kw)
511 if ed.expandedName().localName() != binding_name:
512 print 'Element %s renamed to %s' % (ed.expandedName(), binding_name)
513 template_map['localName'] = binding_module.literal(ed.name(), **kw)
514 template_map['map_update'] = templates.replaceInText("%{namespaceReference}.addCategoryObject('elementBinding', %{localName}, %{class})", **template_map)
515 else:
516 template_map['scope'] = binding_module.literal(ed.scope(), **kw)
517 if ed.annotation() is not None:
518 template_map['documentation'] = binding_module.literal(unicode(ed.annotation()))
519 if ed.abstract():
520 template_map['abstract'] = binding_module.literal(ed.abstract(), **kw)
521 if ed.nillable():
522 template_map['nillable'] = binding_module.literal(ed.nillable(), **kw)
523 if ed.default():
524 template_map['defaultValue'] = binding_module.literal(ed.default(), **kw)
525 template_map['typeDefinition'] = binding_module.literal(ed.typeDefinition(), **kw)
526 if ed.substitutionGroupAffiliation():
527 template_map['substitution_group'] = binding_module.literal(ed.substitutionGroupAffiliation(), **kw)
528 aux_init = []
529 for k in ( 'nillable', 'abstract', 'scope', 'documentation' ):
530 if k in template_map:
531 aux_init.append('%s=%s' % (k, template_map[k]))
532 template_map['element_aux_init'] = ''
533 if 0 < len(aux_init):
534 template_map['element_aux_init'] = ', ' + ', '.join(aux_init)
535
536 return template_map
537
539 binding_module = generator.moduleForComponent(ctd)
540 outf = binding_module.bindingIO()
541
542 content_type = None
543 prolog_template = None
544 template_map = { }
545 binding_name = template_map['ctd'] = binding_module.literal(ctd, **kw)
546 if (ctd.expandedName() is not None) and (ctd.expandedName().localName() != binding_name):
547 print 'Complex type %s renamed to %s' % (ctd.expandedName(), binding_name)
548
549 base_type = ctd.baseTypeDefinition()
550 content_type_tag = ctd._contentTypeTag()
551
552 template_map['base_type'] = binding_module.literal(base_type, **kw)
553 template_map['namespaceReference'] = binding_module.literal(ctd.bindingNamespace(), **kw)
554 template_map['expanded_name'] = binding_module.literal(ctd.expandedName(), **kw)
555 template_map['simple_base_type'] = binding_module.literal(None, **kw)
556 template_map['contentTypeTag'] = content_type_tag
557 template_map['is_abstract'] = repr(not not ctd.abstract())
558
559 need_content = False
560 content_basis = None
561 if (ctd.CT_SIMPLE == content_type_tag):
562 content_basis = ctd.contentType()[1]
563 template_map['simple_base_type'] = binding_module.literal(content_basis, **kw)
564 elif (ctd.CT_MIXED == content_type_tag):
565 content_basis = ctd.contentType()[1]
566 need_content = True
567 elif (ctd.CT_ELEMENT_ONLY == content_type_tag):
568 content_basis = ctd.contentType()[1]
569 need_content = True
570 need_content = False
571
572 prolog_template = '''
573 # Complex type %{ctd} with content type %{contentTypeTag}
574 class %{ctd} (%{superclass}):
575 _TypeDefinition = %{simple_base_type}
576 _ContentTypeTag = pyxb.binding.basis.complexTypeDefinition._CT_%{contentTypeTag}
577 _Abstract = %{is_abstract}
578 _ExpandedName = %{expanded_name}
579 '''
580
581
582
583
584 inherits_from_base = True
585 template_map['superclass'] = binding_module.literal(base_type, **kw)
586 if ctd._isHierarchyRoot():
587 inherits_from_base = False
588 template_map['superclass'] = 'pyxb.binding.basis.complexTypeDefinition'
589 assert base_type.nameInBinding() is not None
590
591
592 class_keywords = frozenset(basis.complexTypeDefinition._ReservedSymbols)
593 class_unique = set()
594
595
596
597
598
599
600
601 element_name_map = { }
602 element_uses = []
603
604 definitions = []
605
606 definitions.append('# Base type is %{base_type}')
607
608
609
610
611
612 if isinstance(content_basis, xs.structures.Particle):
613 plurality_data = content_basis.pluralityData().combinedPlurality()
614
615 outf.postscript().append("\n\n")
616 for (ed, is_plural) in plurality_data.items():
617
618 ef_map = ed._templateMap()
619 if ed.scope() == ctd:
620 ef_map.update(elementDeclarationMap(ed, binding_module, **kw))
621 aux_init = []
622 ef_map['is_plural'] = repr(is_plural)
623 element_uses.append(templates.replaceInText('%{use}.name() : %{use}', **ef_map))
624 if 0 == len(aux_init):
625 ef_map['aux_init'] = ''
626 else:
627 ef_map['aux_init'] = ', ' + ', '.join(aux_init)
628 ef_map['element_binding'] = utility.PrepareIdentifier('%s_elt' % (ef_map['id'],), class_unique, class_keywords, private=True)
629 if ed.annotation() is not None:
630 ef_map['documentation'] = binding_module.literal(unicode(ed.annotation()))
631 else:
632 ef_map['documentation'] = binding_module.literal(None)
633 if ed.scope() != ctd:
634 definitions.append(templates.replaceInText('''
635 # Element %{id} (%{name}) inherited from %{decl_type_en}''', decl_type_en=unicode(ed.scope().expandedName()), **ef_map))
636 continue
637
638 if ed.expandedName().localName() != ef_map['id']:
639 print 'Element use %s.%s renamed to %s' % (ctd.expandedName(), ed.expandedName(), ef_map['id'])
640 definitions.append(templates.replaceInText('''
641 # Element %{name} uses Python identifier %{id}
642 %{use} = pyxb.binding.content.ElementUse(%{name_expr}, '%{id}', '%{key}', %{is_plural}%{aux_init})
643 ''', name_expr=binding_module.literal(ed.expandedName(), **kw), **ef_map))
644
645 if basis.BINDING_STYLE_ACCESSOR == generator.bindingStyle():
646 definitions.append(templates.replaceInText('''
647 def %{inspector} (self):
648 """Get the value of the %{name} element."""
649 return self.%{use}.value(self)
650 def %{mutator} (self, new_value):
651 """Set the value of the %{name} element. Raises BadValueTypeException
652 if the new value is not consistent with the element's type."""
653 return self.%{use}.set(self, new_value)''', **ef_map))
654 if is_plural:
655 definitions.append(templates.replaceInText('''
656 def %{appender} (self, new_value):
657 """Add the value as another occurrence of the %{name} element. Raises
658 BadValueTypeException if the new value is not consistent with the
659 element's type."""
660 return self.%{use}.append(self, new_value)''', **ef_map))
661 elif basis.BINDING_STYLE_PROPERTY == generator.bindingStyle():
662 definitions.append(templates.replaceInText('''
663 %{inspector} = property(%{use}.value, %{use}.set, None, %{documentation})
664 ''', **ef_map))
665 else:
666 raise pyxb.LogicError('Unexpected binding style %s' % (generator.bindingStyle(),))
667 outf.postscript().append(templates.replaceInText('''
668 %{ctd}._AddElement(pyxb.binding.basis.element(%{name_expr}, %{typeDefinition}%{element_aux_init}))
669 ''', name_expr=binding_module.literal(ed.expandedName(), **kw), ctd=template_map['ctd'], **ef_map))
670
671 (particle_val, lines) = GenerateContentParticle(ctd=ctd, particle=content_basis, binding_module=binding_module, **kw)
672 if lines:
673 outf.postscript().append("\n".join(lines))
674 outf.postscript().append("\n")
675 outf.postscript().append(templates.replaceInText('%{ctd}._ContentModel = %{particle_val}', ctd=template_map['ctd'], particle_val=particle_val))
676 outf.postscript().append("\n")
677
678 if need_content:
679 PostscriptItems.append(templates.replaceInText('''
680 %{ctd}._Content = %{particle}
681 ''', **template_map))
682
683
684 attribute_uses = []
685
686
687
688
689
690
691
692
693 for au in ctd.attributeUses():
694 ad = au.attributeDeclaration()
695 assert isinstance(ad.scope(), xs.structures.ComplexTypeDefinition), 'unexpected scope %s' % (ad.scope(),)
696 au_map = ad._templateMap()
697 if ad.scope() != ctd:
698 definitions.append(templates.replaceInText('''
699 # Attribute %{id} inherited from %{decl_type_en}''', decl_type_en=unicode(ad.scope().expandedName()), **au_map))
700 continue
701 assert isinstance(au_map, dict)
702 aur = au;
703 while aur.restrictionOf() is not None:
704 aur = aur.restrictionOf()
705 if au != aur:
706
707 au_map = aur.attributeDeclaration()._templateMap().copy()
708 definitions.append(templates.replaceInText('''
709 # Attribute %{id} is restricted from parent''', **au_map))
710
711 assert ad.typeDefinition() is not None
712 au_map['attr_type'] = binding_module.literal(ad.typeDefinition(), **kw)
713
714 vc_source = ad
715 if au.valueConstraint() is not None:
716 vc_source = au
717 aux_init = []
718 if vc_source.fixed() is not None:
719 aux_init.append('fixed=True')
720 aux_init.append('unicode_default=%s' % (binding_module.literal(vc_source.fixed(), **kw),))
721 elif vc_source.default() is not None:
722 aux_init.append('unicode_default=%s' % (binding_module.literal(vc_source.default(), **kw),))
723 if au.required():
724 aux_init.append('required=True')
725 if au.prohibited():
726 aux_init.append('prohibited=True')
727 if 0 == len(aux_init):
728 au_map['aux_init'] = ''
729 else:
730 aux_init.insert(0, '')
731 au_map['aux_init'] = ', '.join(aux_init)
732 if ad.annotation() is not None:
733 au_map['documentation'] = binding_module.literal(unicode(ad.annotation()))
734 else:
735 au_map['documentation'] = binding_module.literal(None)
736
737 attribute_uses.append(templates.replaceInText('%{use}.name() : %{use}', **au_map))
738 if ad.expandedName().localName() != au_map['id']:
739 print 'Attribute %s.%s renamed to %s' % (ctd.expandedName(), ad.expandedName(), au_map['id'])
740 definitions.append(templates.replaceInText('''
741 # Attribute %{name} uses Python identifier %{id}
742 %{use} = pyxb.binding.content.AttributeUse(%{name_expr}, '%{id}', '%{key}', %{attr_type}%{aux_init})''', name_expr=binding_module.literal(ad.expandedName(), **kw), **au_map))
743 if au.prohibited():
744 if basis.BINDING_STYLE_ACCESSOR == generator.bindingStyle():
745 definitions.append(templates.replaceInText('''
746 # Attribute %{id} marked prohibited in this type
747 def %{inspector} (self):
748 raise pyxb.ProhibitedAttributeError("Attribute %{name} is prohibited in %{ctd}")
749 def %{mutator} (self, new_value):
750 raise pyxb.ProhibitedAttributeError("Attribute %{name} is prohibited in %{ctd}")
751 ''', ctd=template_map['ctd'], **au_map))
752 elif basis.BINDING_STYLE_PROPERTY == generator.bindingStyle():
753 definitions.append(templates.replaceInText('''
754 %{inspector} = property()
755 ''', ctd=template_map['ctd'], **au_map))
756
757 else:
758 raise pyxb.LogicError('Unexpected binding style %s' % (generator.bindingStyle(),))
759 else:
760 if basis.BINDING_STYLE_ACCESSOR == generator.bindingStyle():
761 definitions.append(templates.replaceInText('''
762 def %{inspector} (self):
763 """Get the attribute value for %{name}."""
764 return self.%{use}.value(self)
765 def %{mutator} (self, new_value):
766 """Set the attribute value for %{name}. Raises BadValueTypeException
767 if the new value is not consistent with the attribute's type."""
768 return self.%{use}.set(self, new_value)''', **au_map))
769 elif basis.BINDING_STYLE_PROPERTY == generator.bindingStyle():
770 definitions.append(templates.replaceInText('''
771 %{inspector} = property(%{use}.value, %{use}.set, None, %{documentation})
772 ''', ctd=template_map['ctd'], **au_map))
773 else:
774 raise pyxb.LogicError('Unexpected binding style %s' % (generator.bindingStyle(),))
775
776 if ctd.attributeWildcard() is not None:
777 definitions.append('_AttributeWildcard = %s' % (binding_module.literal(ctd.attributeWildcard(), **kw),))
778 if ctd.hasWildcardElement():
779 definitions.append('_HasWildcardElement = True')
780 template_map['attribute_uses'] = ",\n ".join(attribute_uses)
781 template_map['element_uses'] = ",\n ".join(element_uses)
782 if inherits_from_base:
783 map_decl = '''
784 _ElementMap = %{superclass}._ElementMap.copy()
785 _ElementMap.update({
786 %{element_uses}
787 })
788 _AttributeMap = %{superclass}._AttributeMap.copy()
789 _AttributeMap.update({
790 %{attribute_uses}
791 })'''
792 else:
793 map_decl = '''
794 _ElementMap = {
795 %{element_uses}
796 }
797 _AttributeMap = {
798 %{attribute_uses}
799 }'''
800
801 template_map['registration'] = ''
802 if ctd.name() is not None:
803 template_map['registration'] = templates.replaceInText("%{namespaceReference}.addCategoryObject('typeBinding', %{localName}, %{ctd})",
804 localName=binding_module.literal(ctd.name(), **kw), **template_map)
805
806 template = ''.join([prolog_template,
807 " ", "\n ".join(definitions), "\n",
808 map_decl, '''
809 %{registration}
810
811 '''])
812
813 outf.write(template, **template_map)
814
816
817 assert ed._scopeIsGlobal()
818
819 binding_module = generator.moduleForComponent(ed)
820 outf = binding_module.bindingIO()
821
822 template_map = elementDeclarationMap(ed, binding_module, **kw)
823 template_map.setdefault('scope', binding_module.literal(None, **kw))
824 template_map.setdefault('map_update', '')
825
826 outf.write(templates.replaceInText('''
827 %{class} = pyxb.binding.basis.element(%{name_expr}, %{typeDefinition}%{element_aux_init})
828 %{namespaceReference}.addCategoryObject('elementBinding', %{class}.name().localName(), %{class})
829 ''', name_expr=binding_module.literal(ed.expandedName(), **kw), **template_map))
830
831 if ed.substitutionGroupAffiliation() is not None:
832 outf.postscript().append(templates.replaceInText('''
833 %{class}._setSubstitutionGroup(%{substitution_group})
834 ''', **template_map))
835
844
866
868 use_map = component._templateMap()
869 class_unique = nsm.uniqueInClass(container)
870 assert isinstance(component, xs.structures._ScopedDeclaration_mixin)
871 unique_name = utility.PrepareIdentifier(component.expandedName().localName(), class_unique)
872 use_map['id'] = unique_name
873 use_map['inspector'] = unique_name
874 use_map['mutator'] = utility.PrepareIdentifier('set' + unique_name[0].upper() + unique_name[1:], class_unique)
875 use_map['use'] = utility.MakeUnique('__' + unique_name.strip('_'), class_unique)
876 assert component._scope() == container
877 assert component.nameInBinding() is None, 'Use %s but binding name %s for %s' % (use_map['use'], component.nameInBinding(), component.expandedName())
878 component.setNameInBinding(use_map['use'])
879 key_name = '%s_%s_%s' % (str(nsm.namespace()), container.nameInBinding(), component.expandedName())
880 use_map['key'] = utility.PrepareIdentifier(key_name, class_unique, private=True)
881 use_map['name'] = unicode(component.expandedName())
882 if isinstance(component, xs.structures.ElementDeclaration) and is_plural:
883 use_map['appender'] = utility.PrepareIdentifier('add' + unique_name[0].upper() + unique_name[1:], class_unique)
884 return use_map
885
947
949 __anonSTDIndex = None
950 __anonCTDIndex = None
951 __uniqueInModule = None
952 __uniqueInClass = None
953
954
955 _UniqueInModule = set([ 'pyxb', 'sys' ])
956
957 __ComponentBindingModuleMap = {}
958
961 __generator = None
962
963 - def __init__ (self, generator, *args, **kw):
977
985
1003
1004 __referencedNamespaces = None
1005
1007 return self.__bindingIO
1008
1009 __moduleUID = None
1014
1016 return str(id(self))
1017
1019 """Return a distinct string recorded in the first 4096 bytes of the binding file.
1020
1021 This is used to ensure uniqueness and avoid overwriting data
1022 belonging to a different binding. The return value comprises
1023 the class-specialized L{_bindingTagPrefix_vx} with the
1024 L{moduleUID}.
1025 """
1026 return '%s:%s' % (self._bindingTagPrefix_vx(), self.moduleUID())
1027
1029 raise pyxb.LogicError('Subclass %s does not define _bindingTagPrefix_vx' % (type(self),))
1030
1032 """Return a block of binding text (comment or code) serving as a preface.
1033
1034 Normally this should describe the module contents."""
1035 return self._bindingPreface_vx()
1038
1039 - def moduleContents (self):
1040 template_map = {}
1041 aux_imports = []
1042 for ns in self.__importedModules:
1043 if isinstance(ns, NamespaceModule):
1044 ns = ns.moduleRecord()
1045 module_path = ns.modulePath()
1046 assert module_path is not None, 'No module path for %s type %s' % (ns, type(ns))
1047 aux_imports.append('import %s' % (module_path,))
1048 template_map['aux_imports'] = "\n".join(aux_imports)
1049 template_map['namespace_decls'] = "\n".join(self.__namespaceDeclarations)
1050 template_map['module_uid'] = self.moduleUID()
1051 template_map['generation_uid_expr'] = repr(self.generator().generationUID())
1052 self._finalizeModuleContents_vx(template_map)
1053 return self.__bindingIO.contents()
1054
1068 __modulePath = None
1069
1072 __bindingFile = None
1073 __bindingFilePath = None
1074
1077
1080
1081 @classmethod
1085
1086 @classmethod
1090
1091 @classmethod
1095 @classmethod
1098 __RecordModuleMap = { }
1099
1117 return self.__componentNameMap.get(component)
1118
1120 assert module_type is None
1121 if NamespaceGroupModule == module_type:
1122 pass
1123 elif NamespaceModule == module_type:
1124 pass
1125 else:
1126 assert module_type is None
1127 return component_module
1128
1147
1149
1150 - def defineNamespace (self, namespace, name, require_unique=True, definition=None, **kw):
1164
1166 rv = self.__referencedNamespaces.get(namespace)
1167 if rv is None:
1168 if namespace.isBuiltinNamespace():
1169 rv = namespace.builtinNamespaceRepresentation()
1170 elif namespace.isUndeclaredNamespace():
1171 rv = namespace.modulePath()
1172 elif isinstance(self, NamespaceModule):
1173 if (self.namespace() == namespace):
1174 rv = 'Namespace'
1175 else:
1176 rv = 'pyxb.namespace.NamespaceForURI(%s)' % (repr(namespace.uri()),)
1177 '''
1178 namespace_module = self.ForNamespace(namespace)
1179 if namespace_module is not None:
1180 self._importModule(namespace_module)
1181 rv = '%s.Namespace' % (namespace_module.modulePath(),)
1182 else:
1183 assert False, 'Unexpected reference to %s' % (namespace,)
1184 #rv = 'pyxb.namespace.NamespaceForURI(%s)' % (repr(namespace.uri()),)
1185 '''
1186 else:
1187 if namespace.prefix():
1188 nsn = 'Namespace_%s' % (namespace.prefix(),)
1189 else:
1190 nsn = 'Namespace'
1191 for im in self.__importedModules:
1192 if isinstance(im, NamespaceModule) and (im.namespace() == namespace):
1193 rv = '%s.Namespace' % (im.modulePath(),)
1194 break
1195 if isinstance(im, NamespaceGroupModule):
1196 irv = im.__referencedNamespaces.get(namespace)
1197 if irv is not None:
1198 rv = self.defineNamespace(namespace, nsn, '%s.%s' % (im.modulePath(), irv), protected=True)
1199 break
1200 if rv is None:
1201 rv = self.defineNamespace(namespace, nsn, protected=True)
1202 assert 0 < len(self.__namespaceDeclarations)
1203 self.__referencedNamespaces[namespace] = rv
1204 return rv
1205
1207 return self.__bindingIO.literal(*args, **kw)
1208
1222
1230
1233 """This class represents a Python module that holds all the
1234 declarations belonging to a specific namespace."""
1235
1238 __namespace = None
1239
1242 __moduleRecord = None
1243
1248 __namespaceGroupModule = None
1249
1250 _UniqueInModule = _ModuleNaming_mixin._UniqueInModule.copy()
1251 _UniqueInModule.update([ 'Namespace', 'CreateFromDOM', 'CreateFromDocument' ])
1252
1255 __namespaceGroupHead = None
1256 __namespaceGroup = None
1257
1260 __components = None
1261
1262 @classmethod
1265 __ComponentModuleMap = { }
1266
1269
1271 ns = self.namespace()
1272 rvl = ['# Namespace %s' % (ns,)]
1273 if ns.prefix() is not None:
1274 rvl.append(' [xmlns:%s]' % (ns.prefix(),))
1275 rvl.append('\n')
1276 return ''.join(rvl)
1277
1282
1285
1286 - def __init__ (self, generator, module_record, mr_scc, components=None, **kw):
1303
1311
1312 - def _finalizeModuleContents_vx (self, template_map):
1313 self.bindingIO().prolog().append(self.bindingIO().expand('''
1314 import pyxb
1315 import pyxb.binding
1316 import pyxb.binding.saxer
1317 import StringIO
1318 import pyxb.utils.utility
1319 import pyxb.utils.domutils
1320 import sys
1321
1322 # Unique identifier for bindings created at the same time
1323 _GenerationUID = %{generation_uid_expr}
1324
1325 # Import bindings for namespaces imported into schema
1326 %{aux_imports}
1327
1328 %{namespace_decls}
1329 ModuleRecord = Namespace.lookupModuleRecordByUID(_GenerationUID, create_if_missing=True)
1330 ModuleRecord._setModule(sys.modules[__name__])
1331
1332 def CreateFromDocument (xml_text, default_namespace=None, location_base=None):
1333 """Parse the given XML and use the document element to create a
1334 Python instance.
1335
1336 @kw default_namespace The L{pyxb.Namespace} instance to use as the
1337 default namespace where there is no default namespace in scope.
1338 If unspecified or C{None}, the namespace of the module containing
1339 this function will be used.
1340
1341 @keyword location_base: An object to be recorded as the base of all
1342 L{pyxb.utils.utility.Location} instances associated with events and
1343 objects handled by the parser. You might pass the URI from which
1344 the document was obtained.
1345 """
1346
1347 if pyxb.XMLStyle_saxer != pyxb._XMLStyle:
1348 dom = pyxb.utils.domutils.StringToDOM(xml_text)
1349 return CreateFromDOM(dom.documentElement)
1350 if default_namespace is None:
1351 default_namespace = Namespace.fallbackNamespace()
1352 saxer = pyxb.binding.saxer.make_parser(fallback_namespace=default_namespace, location_base=location_base)
1353 handler = saxer.getContentHandler()
1354 saxer.parse(StringIO.StringIO(xml_text))
1355 instance = handler.rootObject()
1356 return instance
1357
1358 def CreateFromDOM (node, default_namespace=None):
1359 """Create a Python instance from the given DOM node.
1360 The node tag must correspond to an element declaration in this module.
1361
1362 @deprecated: Forcing use of DOM interface is unnecessary; use L{CreateFromDocument}."""
1363 if default_namespace is None:
1364 default_namespace = Namespace.fallbackNamespace()
1365 return pyxb.binding.basis.element.AnyCreateFromDOM(node, _fallback_namespace=default_namespace)
1366
1367 ''', **template_map))
1368
1369 __components = None
1370 __componentBindingName = None
1371
1381
1384
1454
1455
1456 -def GeneratePython (schema_location=None,
1457 schema_text=None,
1458 namespace=None,
1459 module_prefix_elts=[],
1460 **kw):
1471
1472 import optparse
1473 import re
1476 """Configuration and data for a single binding-generation action."""
1477
1478 _DEFAULT_bindingRoot = '.'
1480 """The directory path into which generated bindings will be written.
1481 @rtype: C{str}"""
1482 return self.__bindingRoot
1486 __bindingRoot = None
1487
1489 if isinstance(module_elts, basestring):
1490 module_elts = module_elts.split('.')
1491 else:
1492 module_elts = module_elts[:]
1493 assert 0 < len(module_elts)
1494 if not inhibit_extension:
1495 assert not module_elts[-1].endswith('.py')
1496 module_elts[-1] = '%s.py' % (module_elts[-1],)
1497 return os.path.join(self.bindingRoot(), *module_elts)
1498
1501 __generateToFiles = None
1502
1504
1505
1506
1507
1508 module_path = None
1509 if isinstance(module, NamespaceModule):
1510 mr = module.moduleRecord()
1511 if mr is None:
1512 return ('/dev/null', None, None)
1513 if self.generationUID() != mr.generationUID():
1514 return ('/dev/null', None, None)
1515 if not self.generateToFiles():
1516 return ('/dev/null', None, None)
1517 if mr.namespace().isBuiltinNamespace() and (not self.allowBuiltinGeneration()):
1518 return ('/dev/null', None, None)
1519 module_path = mr.modulePath()
1520 assert module_path is not None, 'No path specified for module %s' % (mr,)
1521
1522
1523
1524 module_elts = module_path.split('.')
1525 if self.writeForCustomization():
1526 import_file_path = self.__moduleFilePath(module_elts)
1527 module_elts.insert(-1, 'raw')
1528 if not os.path.exists(import_file_path):
1529 raw_module_path = '.'.join(module_elts)
1530 pyxb.utils.utility.OpenOrCreate(import_file_path).write("from %s import *\n" % (raw_module_path,))
1531 binding_file_path = self.__moduleFilePath(module_elts)
1532 try:
1533 binding_file = pyxb.utils.utility.OpenOrCreate(binding_file_path, tag=module.moduleUID())
1534 except OSError, e:
1535 if errno.EEXIST == e.errno:
1536 raise pyxb.BindingGenerationError('Target file %s for module %s bindings exists with other content' % (binding_file_path, mr))
1537 raise
1538 elif isinstance(module, NamespaceGroupModule):
1539 if not self.generateToFiles():
1540 raise pyxb.BindingGenerationError('Generation of namespace groups requires generate-to-files')
1541 module_elts = []
1542 if self.modulePrefix():
1543 module_elts.extend(self.modulePrefix().split('.'))
1544 if self.writeForCustomization():
1545 module_elts.append('raw')
1546 in_use = set()
1547 while True:
1548 module_elts.append(pyxb.utils.utility.PrepareIdentifier('nsgroup', in_use, protected=True))
1549 try:
1550 binding_file_path = self.__moduleFilePath(module_elts)
1551 print 'Attempting group %s uid %s at %s' % (module, module.moduleUID(), binding_file_path)
1552 binding_file = pyxb.utils.utility.OpenOrCreate(binding_file_path, tag=module.moduleUID())
1553 break
1554 except OSError, e:
1555 if errno.EEXIST != e.errno:
1556 raise
1557 module_elts.pop()
1558 module_path = '.'.join(module_elts)
1559 else:
1560 assert False
1561 if self.generateToFiles():
1562 for n in range(len(module_elts)-1):
1563 sub_path = self.__moduleFilePath(module_elts[:1+n], inhibit_extension=True)
1564 init_path = os.path.join(sub_path, '__init__.py')
1565 if not os.path.exists(init_path):
1566 file(init_path, 'w')
1567 return (binding_file_path, binding_file, module_path)
1568
1570 """The directory from which entrypoint schemas specified as
1571 relative file paths will be read."""
1572 return self.__schemaRoot
1574 if not schema_root.endswith(os.sep):
1575 schema_root = schema_root + os.sep
1576 self.__schemaRoot = schema_root
1577 return self
1578 __schemaRoot = None
1579
1581 """Optional string that is stripped from the beginning of
1582 schemaLocation values before loading from them.
1583
1584 This applies only to the values of schemaLocation attributes
1585 in C{import} and C{include} elements. Its purpose is to
1586 convert absolute schema locations into relative ones to allow
1587 offline processing when all schema are available in a local
1588 directory. See C{schemaRoot}.
1589 """
1590 return self.__schemaStrippedPrefix
1594 __schemaStrippedPrefix = None
1595
1597 """Optional map to rewrite schema locations.
1598
1599 This applies only to the values of schemaLocation attributes
1600 in C{import} and C{include} elements. Its purpose is to
1601 convert remote or absolute schema locations into local or
1602 relative ones to allow offline processing when all schema are
1603 available in a local directory. See C{schemaRoot}.
1604 """
1605 return self.__locationPrefixRewriteMap
1612 """Add a rewrite entry for schema locations.
1613
1614 @param prefix : A text prefix that should be removed from
1615 schema location URIs.
1616
1617 @param substituent : The text prefix that should replace
1618 C{prefix} as a prefix in a schema location URI.
1619 """
1620
1621 self.__locationPrefixRewriteMap[prefix] = substituent
1622 return self
1624 """Add a rewrite entry for schema locations.
1625
1626 Parameter values are strings of the form C{pfx=sub}. The
1627 effect is that a schema location that begins with C{pfx} is
1628 rewritten so that it instead begins with C{sub}."""
1629 try:
1630 (prefix, substituent) = prefix_rewrite.split('=', 1)
1631 except:
1632 raise
1633 self.addLocationPrefixRewrite(prefix, substituent)
1634 __locationPrefixMap = {}
1635
1637 """A list of locations from which entrypoint schemas are to be
1638 read.
1639
1640 The values in the list are either URIs, or tuples consisting
1641 of a value and a callable which, when passed the generator
1642 object and the value, will return a
1643 L{pyxb.xmlschema.structures.Schema} instance. See
1644 L{addSchemaLocation}.
1645
1646 See also L{addSchemaLocation} and L{schemas}.
1647 """
1648 return self.__schemaLocationList
1654 """Add the location of an entrypoint schema.
1655
1656 @param schema_location: The location of the schema. This
1657 should be a URL; if the schema location does not have a URL
1658 scheme (e.g., C{http:}), it is assumed to be a file, and if it
1659 is not an absolute path is located relative to the
1660 C{schemaRoot}.
1661
1662 @keyword converter: Optional callable that will be invoked
1663 with the generator instance and the schema location, and is
1664 expected to return a L{pyxb.xmlschema.structures.Schema}
1665 instance. If absent, the contents of the location are
1666 converted directly.
1667
1668 @note: The C{converter} argument derives from WSDL support: we
1669 need to add to the sequence of schema locations a URI of
1670 something that will not parse as a schema, but does have inner
1671 material that can if treated properly. "Treated properly" may
1672 include having the archive path and other namespace
1673 manipulations configured before anything is done to it.
1674 """
1675 self.__schemaLocationList.append( (schema_location, converter) )
1676 return self
1678 """Add the location of an entrypoint schema. The provided
1679 value should be a URL; if it does not have a URL scheme (e.g.,
1680 C{http:}), it is assumed to be a file, and if it is not an
1681 absolute path is located relative to the C{schemaRoot}."""
1682 self.addSchemaLocation(schema_location)
1683 __schemaLocationList = None
1684
1686 """Schema for which bindings should be generated.
1687
1688 These may be L{Schema<pyxb.xmlschema.structures.Schema>}
1689 instances, or strings; the latter is preferred, and is parsed
1690 into a Schema instance when required.
1691
1692 This is the list of entrypoint schemas for binding generation.
1693 Values in L{schemaLocationList} are read and converted into
1694 schema, then appended to this list. Values from L{moduleList}
1695 are applied starting with the first schema in this list.
1696 """
1697 return self.__schemas[:]
1705 __schemas = None
1706
1708 """The set of L{namespaces<pyxb.namespace.Namespace>} for
1709 which bindings will be generated.
1710
1711 This is the set of namespaces read from entrypoint schema,
1712 closed under reference to namespaces defined by schema import.
1713
1714 @rtype: C{set}
1715 """
1716 return self.__namespaces.copy()
1724 __namespaces = None
1725
1727 """A list of module names to be applied in order to the namespaces of entrypoint schemas"""
1728 return self.__moduleList[:]
1733
1735 """Add a module name corresponding to an entrypoint schema.
1736
1737 The namespace defined by the corresponding schema will be
1738 written to a binding using the given module name, adjusted by
1739 L{modulePrefix}."""
1740 self.__moduleList.append(module_name)
1741 return self
1742 __moduleList = None
1743
1745 """The prefix for binding modules.
1746
1747 The base name for the module holding a binding is taken from
1748 the moduleList, moduleMap, or an XMLNS prefix associated with
1749 the namespace in a containing schema. This value, if present,
1750 is used as a prefix to allow a deeper module hierarchy."""
1751 return self.__modulePrefix
1755 __modulePrefix = None
1756
1758 """A map from namespace URIs to the module to be used for the
1759 corresponding generated binding.
1760
1761 Module values are adjusted by L{modulePrefix} if that has been
1762 specified.
1763
1764 An entry in this map for a namespace supersedes the module
1765 specified in moduleList if the namespace is defined by an
1766 entrypoint schema.
1767
1768 @return: A reference to the namespace module map.
1769 """
1770 return self.__namespaceModuleMap
1771 __namespaceModuleMap = None
1772
1774 """A colon-separated list of paths from which namespace
1775 archives can be read.
1776
1777 The default path is the contents of the C{PYXB_ARCHIVE_PATH}
1778 environment variable, or the standard path configured at
1779 installation time. Any file with the extension C{.wxs} found
1780 in one of these directories is examined to see whether it is a
1781 namespace archive.
1782 """
1783 return self.__archivePath
1787 __archivePath = None
1788
1790 """A frozenset of namespaces that many not be loaded from an archive."""
1791 return frozenset(self.__noLoadNamespaces)
1793 """Record the set of namespaces that should not be loaded from an archive.
1794
1795 The expectation is that any required entities in the namespace
1796 will be defined by loading schema."""
1797 self.__noLoadNamespaces.clear()
1798 self.__noLoadNamespaces.update([ pyxb.namespace.NamespaceInstance(_ns) for _ns in namespace_set ])
1800 """Mark that the specified namespace should not be loaded from an archive.
1801
1802 Use this when you are generating bindings for an application
1803 that has a restricted profile of a namespace that would
1804 otherwise be read from an archive. Be aware that this removes
1805 any knowledge of any archive in which this namespace is
1806 present as a non-private member."""
1807 self.__noLoadNamespaces.add(pyxb.namespace.NamespaceInstance(namespace))
1808 __noloadNamespaces = None
1809
1811 """A list of paths to archives that should be loaded, in order, prior to parsing schema."""
1812 return frozenset(self.__preLoadArchives)
1814 """Name of a file containing a stored archive from which
1815 namespaces should be read prior to processing schema.
1816
1817 Files to be pre-loaded are not affected by
1818 C{noLoadNamespace}."""
1819 self.__preLoadArchives.append(archive_file)
1823 __preLoadArchives = None
1824
1826 """Optional file into which the archive of namespaces will be written.
1827
1828 Subsequent generation actions can read pre-parsed namespaces
1829 from this file, and therefore reference the bindings that were
1830 built earlier rather than re-generating them.
1831
1832 The file name should normally end with C{.wxs}."""
1833 return self.__archiveToFile
1837 __archiveToFile = None
1838
1852 """Indicates, for specific namespaces, whether their
1853 visibility in the archive should be public or private."""
1854 return self.__namespaceVisibilityMap.copy()
1855 __namespaceVisibilityMap = None
1856
1858 """Indicates whether unmentioned namespaces will be public or private (default) in the archive.
1859
1860 A namespace is I{mentioned} if it is the target namespace of
1861 an entrypoint schema, or appears in a namespace visibility
1862 specification. I.e., this default applies only to namespaces
1863 that are modified as a result of including some schema, which
1864 is generally a local customization of something.
1865 """
1866 return self.__defaultNamespacePublic
1869 __defaultNamespacePublic = None
1870
1872 """Indicates whether the bindings should validate mutations
1873 against the content model."""
1874 return self.__validateChanges
1879 __validateChanges = None
1880
1881 _DEFAULT_bindingStyle = basis.CURRENT_BINDING_STYLE
1883 """The style of Python used in generated bindings.
1884
1885 C{accessor} means values are private variables accessed
1886 through inspector and mutator methods.
1887
1888 C{property} means values are private variables accessed
1889 through a Python property.
1890 """
1891 return self.__bindingStyle
1896 __bindingStyle = None
1897
1899 """Indicates whether the binding Python code should be written into a sub-module for customization.
1900
1901 If enabled, a module C{path.to.namespace} will be written to
1902 the file C{path/to/raw/namespace.py}, so that the file
1903 C{path/to/namespace.py} can import it and override behavior."""
1904 return self.__writeForCustomization
1908 __writeForCustomization = None
1909
1911 """Indicates whether the code generator is permitted to
1912 process namespace for which no module path can be determined.
1913
1914 Use this only when generating bindings that will not be
1915 referenced by other bindings."""
1916 return self.__allowAbsentModule
1920 __allowAbsentModule = None
1921
1923 """Indicates whether bindings will be written for namespaces that are built-in to PyXB.
1924
1925 This must be enabled when building bindings for the XML,
1926 XMLSchema instance, and other built-in namespaces. Normally
1927 generation of these namespaces is inhibited lest it produce
1928 inconsistencies."""
1929 return self.__allowBuiltinGeneration
1933 __allowBuiltinGeneration = None
1934
1936 """The directory path into which any content retrieved by URI will be written.
1937
1938 This serves as a local cache, and to give you an opportunity
1939 to inspect material retrieved from some other system.
1940 @rtype: C{str}"""
1941 return self.__uriContentArchiveDirectory
1944 __uriContentArchiveDirectory = None
1945
1947 """Create a configuration to be used for generating bindings.
1948
1949 Arguments are treated as additions to the schema location list
1950 after all keywords have been processed.
1951
1952 @keyword binding_root: Invokes L{setBindingRoot}
1953 @keyword schema_root: Invokes L{setSchemaRoot}
1954 @keyword schema_stripped_prefix: Invokes L{setSchemaStrippedPrefix}
1955 @keyword location_prefix_rewrite_map: Invokes L{setLocationPrefixRewriteMap}
1956 @keyword schema_location_list: Invokes L{setSchemaLocationList}
1957 @keyword module_list: Invokes L{_setModuleList}
1958 @keyword module_prefix: Invokes L{setModulePrefix}
1959 @keyword archive_path: Invokes L{setArchivePath}
1960 @keyword no_load_namespaces: Invokes L{_setNoLoadNamespaces}
1961 @keyword pre_load_archives: Invokes L{_setPreLoadArchives}
1962 @keyword archive_to_file: Invokes L{setArchiveToFile}
1963 @keyword public_namespace: Invokes L{setNamespaceVisibility}
1964 @keyword private_namespace: Invokes L{setNamespaceVisibility}
1965 @keyword default_namespace_public: Invokes L{setDefaultNamespacePublic}
1966 @keyword validate_changes: Invokes L{setValidateChanges}
1967 @keyword binding_style: Invokes L{setBindingStyle}
1968 @keyword namespace_module_map: Initializes L{namespaceModuleMap}
1969 @keyword schemas: Invokes L{setSchemas}
1970 @keyword namespaces: Invokes L{setNamespaces}
1971 @keyword write_for_customization: Invokes L{setWriteForCustomization}
1972 @keyword allow_builtin_generation: Invokes L{setAllowBuiltinGeneration}
1973 @keyword allow_absent_module: Invokes L{setAllowAbsentModule}
1974 @keyword generate_to_files: Sets L{generateToFiles}
1975 @keyword uri_content_archive_directory: Invokes L{setUriContentArchiveDirectory}
1976 """
1977 argv = kw.get('argv', None)
1978 if argv is not None:
1979 kw = {}
1980 self.__bindingRoot = kw.get('binding_root', self._DEFAULT_bindingRoot)
1981 self.__schemaRoot = kw.get('schema_root', '.')
1982 self.__schemaStrippedPrefix = kw.get('schema_stripped_prefix')
1983 self.__locationPrefixRewriteMap = kw.get('location_prefix_rewrite_map', {})
1984 self.__schemas = []
1985 self.__schemaLocationList = kw.get('schema_location_list', [])[:]
1986 self.__moduleList = kw.get('module_list', [])[:]
1987 self.__modulePrefix = kw.get('module_prefix')
1988 self.__archivePath = kw.get('archive_path', pyxb.namespace.archive.GetArchivePath())
1989 self.__noLoadNamespaces = kw.get('no_load_namespaces', set()).copy()
1990 self.__preLoadArchives = kw.get('pre_load_archives', [])[:]
1991 self.__archiveToFile = kw.get('archive_to_file')
1992 self.__namespaceVisibilityMap = {}
1993 self._setNamespaceVisibilities(kw.get('public_namespaces', set()), kw.get('private_namespaces', set()))
1994 self.__defaultNamespacePublic = kw.get('default_namespace_public', False)
1995 self.__validateChanges = kw.get('validate_changes', True)
1996 self.__bindingStyle = kw.get('binding_style', self._DEFAULT_bindingStyle)
1997 self.__namespaceModuleMap = kw.get('namespace_module_map', {}).copy()
1998 self.__schemas = kw.get('schemas', [])[:]
1999 self.__namespaces = set(kw.get('namespaces', []))
2000 self.__writeForCustomization = kw.get('write_for_customization', False)
2001 self.__allowBuiltinGeneration = kw.get('allow_builtin_generation', False)
2002 self.__allowAbsentModule = kw.get('allow_absent_module', False)
2003 self.__generateToFiles = kw.get('generate_to_files', True)
2004 self.__uriContentArchiveDirectory = kw.get('uri_content_archive_directory')
2005
2006 if argv is not None:
2007 self.applyOptionValues(*self.optionParser().parse_args(argv))
2008 [ self.addSchemaLocation(_a) for _a in args ]
2009
2010 self.__generationUID = pyxb.utils.utility.UniqueIdentifier()
2011
2012 pyxb.namespace.XML.validateComponentModel()
2013
2014 __stripSpaces_re = re.compile('\s\s\s+')
2017
2018 __OptionSetters = (
2019 ('binding_root', setBindingRoot),
2020 ('schema_root', setSchemaRoot),
2021 ('schema_stripped_prefix', setSchemaStrippedPrefix),
2022 ('location_prefix_rewrite', argAddLocationPrefixRewrite),
2023 ('schema_location', setSchemaLocationList),
2024 ('module', _setModuleList),
2025 ('module_prefix', setModulePrefix),
2026 ('archive_path', setArchivePath),
2027 ('no_load_namespace', _setNoLoadNamespaces),
2028 ('pre_load_archive', _setPreLoadArchives),
2029 ('archive_to_file', setArchiveToFile),
2030 ('default_namespace_public', setDefaultNamespacePublic),
2031 ('binding_style', setBindingStyle),
2032 ('validate_changes', setValidateChanges),
2033 ('write_for_customization', setWriteForCustomization),
2034 ('allow_builtin_generation', setAllowBuiltinGeneration),
2035 ('allow_absent_module', setAllowAbsentModule),
2036 ('uri_content_archive_directory', setUriContentArchiveDirectory)
2037 )
2049
2051 if argv is None:
2052 argv = sys.argv[1:]
2053 (options, args) = self.optionParser().parse_args(argv)
2054 self.applyOptionValues(options, args)
2055 return self
2056
2059 __generationUID = None
2060
2062 """Return an C{optparse.OptionParser} instance tied to this configuration.
2063
2064 @param reset: If C{False} (default), a parser created in a
2065 previous invocation will be returned. If C{True}, any
2066 previous option parser is discarded and a new one created.
2067 @type reset: C{bool}
2068 """
2069 if reset or (self.__optionParser is None):
2070 parser = optparse.OptionParser(usage="%prog [options] [more schema locations...]",
2071 version='%%prog from PyXB %s' % (pyxb.__version__,),
2072 description='Generate bindings from a set of XML schemas')
2073
2074 group = optparse.OptionGroup(parser, 'Identifying Schema', 'Specify and locate schema for which bindings should be generated.')
2075 group.add_option('--schema-location', '-u', metavar="FILE_or_URL",
2076 action='append',
2077 help=self.__stripSpaces(self.argAddSchemaLocation.__doc__))
2078 group.add_option('--schema-root', metavar="DIRECTORY",
2079 help=self.__stripSpaces(self.schemaRoot.__doc__))
2080 group.add_option('--schema-stripped-prefix', metavar="TEXT", type='string',
2081 help=self.__stripSpaces(self.schemaStrippedPrefix.__doc__))
2082 group.add_option('--location-prefix-rewrite', metavar="TEXT", type='string',
2083 help=self.__stripSpaces(self.argAddLocationPrefixRewrite.__doc__))
2084 group.add_option('--uri-content-archive-directory', metavar="DIRECTORY",
2085 help=self.__stripSpaces(self.uriContentArchiveDirectory.__doc__))
2086 parser.add_option_group(group)
2087
2088 group = optparse.OptionGroup(parser, 'Configuring Bindings', 'Specify where generated bindings should be written, and how they will be accessed from Python.')
2089 group.add_option('--module', '-m', metavar="MODULE",
2090 action='append',
2091 help=self.__stripSpaces(self.addModuleName.__doc__))
2092 group.add_option('--module-prefix', metavar="MODULE",
2093 help=self.__stripSpaces(self.modulePrefix.__doc__))
2094 group.add_option('--binding-root', metavar="DIRECTORY",
2095 help=self.__stripSpaces(self.bindingRoot.__doc__))
2096 group.add_option('-r', '--write-for-customization',
2097 action='store_true', dest='write_for_customization',
2098 help=self.__stripSpaces(self.writeForCustomization.__doc__ + ' This option turns on the feature.'))
2099 group.add_option('--no-write-for-customization',
2100 action='store_false', dest='write_for_customization',
2101 help=self.__stripSpaces(self.writeForCustomization.__doc__ + ' This option turns off the feature (I{default}).'))
2102 parser.add_option_group(group)
2103
2104 group = optparse.OptionGroup(parser, 'Reading Namespace Archives', 'Locating and loading (or inhibiting load of) namespace archives.')
2105 group.add_option('--archive-path', metavar="PATH",
2106 help=self.__stripSpaces(self.archivePath.__doc__))
2107 group.add_option('--pre-load-archive', metavar="FILE",
2108 action='append',
2109 help=self.__stripSpaces(self.addPreLoadArchive.__doc__))
2110 group.add_option('--no-load-namespace', metavar="URI",
2111 action='append',
2112 help=self.__stripSpaces(self.addNoLoadNamespace.__doc__))
2113 parser.add_option_group(group)
2114
2115 group = optparse.OptionGroup(parser, 'Writing Namespace Archives', 'Control the location and content of a namespace archive corresponding to a binding generation.')
2116 group.add_option('--archive-to-file', metavar="FILE",
2117 help=self.__stripSpaces(self.archiveToFile.__doc__))
2118 group.add_option('--public-namespace', metavar="URI",
2119 action='append',
2120 help=self.__stripSpaces(self.namespaceVisibilityMap.__doc__ + ' This option adds the namespace as a public archive member.'))
2121 group.add_option('--private-namespace', metavar="URI",
2122 action='append',
2123 help=self.__stripSpaces(self.namespaceVisibilityMap.__doc__ + ' This option adds the namespace as a private archive member.'))
2124 group.add_option('--default-namespace-public',
2125 action="store_true", dest='default_namespace_public',
2126 help=self.__stripSpaces(self.defaultNamespacePublic.__doc__ + ' This option makes the default C{public} (I{default}).'))
2127 group.add_option('--default-namespace-private',
2128 action="store_false", dest='default_namespace_public',
2129 help=self.__stripSpaces(self.defaultNamespacePublic.__doc__ + ' This option makes the default C{private}.'))
2130 parser.add_option_group(group)
2131
2132 group = optparse.OptionGroup(parser, 'Configuring Binding Code Generation', "Control the style and content of the generated bindings. This is not well-supported, and you are advised to pretend these options don't exist.")
2133 group.add_option('--binding-style',
2134 type='choice', choices=basis.BINDING_STYLES,
2135 help=self.__stripSpaces(self.bindingStyle.__doc__))
2136 group.add_option('--validate-changes',
2137 action='store_true', dest='validate_changes',
2138 help=self.__stripSpaces(self.validateChanges.__doc__ + ' This option turns on validation (default).'))
2139 group.add_option('--no-validate-changes',
2140 action='store_false', dest='validate_changes',
2141 help=self.__stripSpaces(self.validateChanges.__doc__ + ' This option turns off validation.'))
2142 parser.add_option_group(group)
2143
2144 group = optparse.OptionGroup(parser, 'Maintainer Options', "Don't use these. They don't exist. If they did, they'd do different things at different times, and if you used them you'd probably be sorry.")
2145 group.add_option('--allow-absent-module',
2146 action='store_true', dest='allow_absent_module',
2147 help=self.__stripSpaces(self.allowAbsentModule.__doc__ + ' This option turns on the feature.'))
2148 group.add_option('--no-allow-absent-module',
2149 action='store_false', dest='allow_absent_module',
2150 help=self.__stripSpaces(self.allowAbsentModule.__doc__ + ' This option turns off the feature (default).'))
2151 group.add_option('--allow-builtin-generation',
2152 action='store_true', dest='allow_builtin_generation',
2153 help=self.__stripSpaces(self.allowBuiltinGeneration.__doc__ + ' This option turns on the feature.'))
2154 group.add_option('--no-allow-builtin-generation',
2155 action='store_false', dest='allow_builtin_generation',
2156 help=self.__stripSpaces(self.allowBuiltinGeneration.__doc__ + ' This option turns off the feature (default).'))
2157 parser.add_option_group(group)
2158
2159 self.__optionParser = parser
2160 return self.__optionParser
2161 __optionParser = None
2162
2164 """Return a command line option sequence that could be used to
2165 construct an equivalent configuration.
2166
2167 @note: If you extend the option parser, as is done by
2168 C{pyxbgen}, this may not be able to reconstruct the correct
2169 command line."""
2170 opts = []
2171 module_list = self.moduleList()
2172 schema_list = self.schemaLocationList()
2173 while module_list and schema_list:
2174 ml = module_list.pop(0)
2175 sl = schema_list.pop(0)
2176 if isinstance(sl, tuple):
2177 sl = sl[0]
2178 opts.extend(['--schema-location=' + sl, '--module=' + ml])
2179 for sl in schema_list:
2180 opts.append('--schema-location=' + sl)
2181 if self.schemaRoot() is not None:
2182 opts.append('--schema-root=' + self.schemaRoot())
2183 if self.schemaStrippedPrefix() is not None:
2184 opts.append('--schema-stripped-prefix=%s' + self.schemaStrippedPrefix())
2185 for (pfx, sub) in self.locationPrefixRewriteMap():
2186 opts.append('--location-prefix-rewrite=%s=%s' % (pfx, sub))
2187 if self.modulePrefix() is not None:
2188 opts.append('--module-prefix=' + self.modulePrefix())
2189 opts.append('--binding-root=' + self.bindingRoot())
2190 if self.archivePath() is not None:
2191 opts.append('--archive-path=' + self.archivePath())
2192 for ns in self.noLoadNamespaces():
2193 opts.append('--no-load-namespace=' + ns.uri())
2194 for fps in self.preLoadArchives():
2195 opts.append('--pre-load-archive=' + fp)
2196 if self.archiveToFile() is not None:
2197 opts.append('--archive-to-file=' + self.archiveToFile())
2198 for (ns, visibility) in self._namespaceVisibilityMap():
2199 if visibility:
2200 opts.append('--public-namespace=' + ns.uri())
2201 else:
2202 opts.append('--private-namespace=' + ns.uri())
2203 if self.defaultNamespacePublic():
2204 opts.append('--default-namespace-public')
2205 else:
2206 opts.append('--default-namespace-private')
2207 for (val, opt) in ( (self.validateChanges(), 'validate-changes'),
2208 (self.writeForCustomization(), 'write-for-customization'),
2209 (self.allowAbsentModule(), 'allow-absent-module'),
2210 (self.allowBuiltinGeneration(), 'allow-builtin-generation') ):
2211 if val:
2212 opts.append('--' + opt)
2213 else:
2214 opts.append('--no-' + opt)
2215 if self.uriContentArchiveDirectory() is not None:
2216 opts.append('--uri-content-archive-directory=%s' + self.uriContentArchiveDirectory())
2217 return opts
2218
2224
2239
2240 __didResolveExternalSchema = False
2242 if self.__didResolveExternalSchema and (not reset):
2243 raise pyxb.PyXBException('Cannot resolve external schema multiple times')
2244
2245 required_archives = pyxb.namespace.archive.NamespaceArchive.PreLoadArchives(self.archivePath(), self.preLoadArchives())
2246 for nsa in required_archives:
2247 nsa.readNamespaces()
2248 for ns in self.noLoadNamespaces():
2249 assert isinstance(ns, pyxb.namespace.Namespace)
2250 ns.markNotLoadable()
2251 while self.__schemaLocationList:
2252 sl = self.__schemaLocationList.pop(0)
2253 if isinstance(sl, tuple):
2254 (sl, converter) = sl
2255 else:
2256 converter = None
2257 try:
2258 if converter is None:
2259 schema = xs.schema.CreateFromLocation(absolute_schema_location=self.normalizeSchemaLocation(sl),
2260 generation_uid=self.generationUID(),
2261 uri_content_archive_directory=self.uriContentArchiveDirectory())
2262 else:
2263 schema = converter(self, sl)
2264 self.addSchema(schema)
2265 except pyxb.SchemaUniquenessError, e:
2266 print 'WARNING: Skipped redundant translation of %s defining %s' % (e.schemaLocation(), e.namespace())
2267 self.addSchema(e.existingSchema())
2268 for schema in self.__schemas:
2269 if isinstance(schema, basestring):
2270 schema = xs.schema.CreateFromDocument(schema, generation_uid=self.generationUID())
2271 origin = schema.originRecord()
2272 assert origin is not None
2273 module_path = None
2274 if self.__moduleList:
2275 module_path = self.__moduleList.pop(0)
2276 self.__assignModulePath(origin.moduleRecord(), module_path)
2277 assert schema.targetNamespace() == origin.moduleRecord().namespace()
2278 self.addNamespace(schema.targetNamespace())
2279 self.__didResolveExternalSchema = True
2280 self.__bindingModules = None
2281
2307
2309 named_bindable_fn = lambda _c: (isinstance(_c, xs.structures.ElementDeclaration) and _c._scopeIsGlobal()) or _c.isTypeDefinition()
2310 bindable_fn = lambda _c: isinstance(_c, xs.structures.ElementDeclaration) or _c.isTypeDefinition()
2311
2312 self.__moduleRecords = set()
2313 all_components = set()
2314 for origin in self.generationUID().associatedObjects():
2315 mr = origin.moduleRecord()
2316 if not (mr in self.__moduleRecords):
2317
2318
2319 self.__moduleRecords.add(mr)
2320 mr.completeGenerationAssociations()
2321 all_components.update(origin.originatedObjects())
2322
2323 namespaces = set()
2324 for mr in self.__moduleRecords:
2325 if mr.namespace().isBuiltinNamespace() and not self.allowBuiltinGeneration():
2326 continue
2327 namespaces.add(mr.namespace())
2328 pyxb.namespace.resolution.ResolveSiblingNamespaces(namespaces)
2329
2330
2331
2332 for ns in self.namespaces():
2333 self.__namespaceVisibilityMap.setdefault(ns, True)
2334
2335
2336
2337
2338 component_graph = self.__graphFromComponents(all_components, True)
2339
2340 binding_components = set(filter(bindable_fn, component_graph.nodes()))
2341
2342
2343
2344 module_graph = pyxb.utils.utility.Graph()
2345 [ module_graph.addRoot(_mr) for _mr in self.__moduleRecords ]
2346 for (s, t) in component_graph.edges():
2347 module_graph.addEdge(s._objectOrigin().moduleRecord(), t._objectOrigin().moduleRecord())
2348 module_scc_order = module_graph.sccOrder()
2349
2350
2351
2352
2353
2354
2355
2356
2357 for c in binding_components:
2358 assert bindable_fn(c), 'Unexpected %s in binding components' % (type(s),)
2359 c._setBindingNamespace(c._objectOrigin().moduleRecord().namespace())
2360
2361 record_binding_map = {}
2362 unique_in_bindings = set([NamespaceGroupModule._GroupPrefix])
2363 modules = []
2364 for mr_scc in module_scc_order:
2365 scc_modules = [ ]
2366 for mr in mr_scc:
2367
2368
2369 mr._setIsPublic(self.__namespaceVisibilityMap.get(mr.namespace(), self.defaultNamespacePublic()))
2370 self.__assignModulePath(mr)
2371 assert not ((mr.modulePath() is None) and self.generateToFiles()), 'No module path defined for %s' % (mr,)
2372 if (not mr.isPublic()) and (mr.modulePath() is not None):
2373 elts = mr.modulePath().split('.')
2374 elts[-1] = '_%s' % (elts[-1],)
2375 mr.setModulePath('.'.join(elts))
2376 nsm = NamespaceModule(self, mr, mr_scc)
2377 record_binding_map[mr] = nsm
2378 scc_modules.append(nsm)
2379
2380 modules.extend(scc_modules)
2381 if 1 < len(mr_scc):
2382 ngm = NamespaceGroupModule(self, scc_modules)
2383 modules.append(ngm)
2384 for nsm in scc_modules:
2385 nsm.setNamespaceGroupModule(ngm)
2386
2387 component_csets = self.__graphFromComponents(binding_components, False).sccOrder()
2388 bad_order = False
2389 component_order = []
2390 for cset in component_csets:
2391 if 1 < len(cset):
2392 print "COMPONENT DEPENDENCY LOOP of %d components" % (len(cset),)
2393 cg = pyxb.utils.utility.Graph()
2394 for c in cset:
2395 assert bindable_fn(c), 'Unexpected %s in list' % (type(c),)
2396 print ' %s' % (c.expandedName(),)
2397 cg.addNode(c)
2398 for cd in c.bindingRequires(reset=True, include_lax=False):
2399
2400 cg.addEdge(c, cd)
2401
2402 relaxed_order = cg.sccOrder()
2403 for rcs in relaxed_order:
2404 assert 1 == len(rcs)
2405 rcs = rcs[0]
2406 if rcs in cset:
2407 component_order.append(rcs)
2408 else:
2409 component_order.extend(cset)
2410
2411
2412
2413 element_declarations = []
2414 type_definitions = []
2415 for c in component_order:
2416 if isinstance(c, xs.structures.ElementDeclaration) and c._scopeIsGlobal():
2417
2418 nsm = record_binding_map[c._objectOrigin().moduleRecord()]
2419 nsm.bindComponent(c)
2420 element_declarations.append(c)
2421 elif c.isTypeDefinition():
2422 type_definitions.append(c)
2423 else:
2424
2425 pass
2426
2427 simple_type_definitions = []
2428 complex_type_definitions = []
2429 for td in type_definitions:
2430 nsm = record_binding_map[td._objectOrigin().moduleRecord()]
2431 assert nsm is not None, 'No namespace module for %s type %s scope %s namespace %s' % (td.expandedName(), type(td), td._scope(), td.bindingNamespace)
2432 module_context = nsm.bindComponent(td)
2433 assert isinstance(module_context, _ModuleNaming_mixin), 'Unexpected type %s' % (type(module_context),)
2434 if isinstance(td, xs.structures.SimpleTypeDefinition):
2435 _PrepareSimpleTypeDefinition(td, self, nsm, module_context)
2436 simple_type_definitions.append(td)
2437 elif isinstance(td, xs.structures.ComplexTypeDefinition):
2438 _PrepareComplexTypeDefinition(td, self, nsm, module_context)
2439 complex_type_definitions.append(td)
2440 else:
2441 assert False, 'Unexpected component type %s' % (type(td),)
2442
2443 for ngm in modules:
2444 if isinstance(ngm, NamespaceGroupModule):
2445 for m in ngm.namespaceModules():
2446 m.addImportsFrom(ngm)
2447
2448 for std in simple_type_definitions:
2449 GenerateSTD(std, self)
2450 for ctd in complex_type_definitions:
2451 GenerateCTD(ctd, self)
2452 for ed in element_declarations:
2453 GenerateED(ed, self)
2454
2455 return modules
2456
2457 __bindingModules = None
2464
2466 archive_file = self.archiveToFile()
2467 if archive_file is not None:
2468 ns_archive = pyxb.namespace.archive.NamespaceArchive(generation_uid=self.generationUID())
2469 try:
2470 ns_archive.writeNamespaces(pyxb.utils.utility.OpenOrCreate(archive_file))
2471 print 'Saved parsed schema to %s URI' % (archive_file,)
2472 except Exception, e:
2473 print 'Exception saving preprocessed schema to %s: %s' % (archive_file, e)
2474 traceback.print_exception(*sys.exc_info())
2475
2476
2477
2478
2479 if isinstance(e, (AssertionError, AttributeError, TypeError)):
2480 raise
2481
2484