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
945
947 __anonSTDIndex = None
948 __anonCTDIndex = None
949 __uniqueInModule = None
950 __uniqueInClass = None
951
952
953 _UniqueInModule = set([ 'pyxb', 'sys' ])
954
955 __ComponentBindingModuleMap = {}
956
959 __generator = None
960
961 - def __init__ (self, generator, *args, **kw):
975
983
1001
1002 __referencedNamespaces = None
1003
1005 return self.__bindingIO
1006
1007 __moduleUID = None
1012
1014 return str(id(self))
1015
1017 """Return a distinct string recorded in the first 4096 bytes of the binding file.
1018
1019 This is used to ensure uniqueness and avoid overwriting data
1020 belonging to a different binding. The return value comprises
1021 the class-specialized L{_bindingTagPrefix_vx} with the
1022 L{moduleUID}.
1023 """
1024 return '%s:%s' % (self._bindingTagPrefix_vx(), self.moduleUID())
1025
1027 raise pyxb.LogicError('Subclass %s does not define _bindingTagPrefix_vx' % (type(self),))
1028
1030 """Return a block of binding text (comment or code) serving as a preface.
1031
1032 Normally this should describe the module contents."""
1033 return self._bindingPreface_vx()
1036
1037 - def moduleContents (self):
1038 template_map = {}
1039 aux_imports = []
1040 for ns in self.__importedModules:
1041 if isinstance(ns, NamespaceModule):
1042 ns = ns.moduleRecord()
1043 module_path = ns.modulePath()
1044 assert module_path is not None, 'No module path for %s type %s' % (ns, type(ns))
1045 aux_imports.append('import %s' % (module_path,))
1046 template_map['aux_imports'] = "\n".join(aux_imports)
1047 template_map['namespace_decls'] = "\n".join(self.__namespaceDeclarations)
1048 template_map['module_uid'] = self.moduleUID()
1049 template_map['generation_uid_expr'] = repr(self.generator().generationUID())
1050 self._finalizeModuleContents_vx(template_map)
1051 return self.__bindingIO.contents()
1052
1066 __modulePath = None
1067
1070 __bindingFile = None
1071 __bindingFilePath = None
1072
1075
1078
1079 @classmethod
1083
1084 @classmethod
1088
1089 @classmethod
1093 @classmethod
1096 __RecordModuleMap = { }
1097
1115 return self.__componentNameMap.get(component)
1116
1118 assert module_type is None
1119 if NamespaceGroupModule == module_type:
1120 pass
1121 elif NamespaceModule == module_type:
1122 pass
1123 else:
1124 assert module_type is None
1125 return component_module
1126
1145
1147
1148 - def defineNamespace (self, namespace, name, require_unique=True, definition=None, **kw):
1162
1164 rv = self.__referencedNamespaces.get(namespace)
1165 if rv is None:
1166 if namespace.isBuiltinNamespace():
1167 rv = namespace.builtinNamespaceRepresentation()
1168 elif namespace.isUndeclaredNamespace():
1169 rv = namespace.modulePath()
1170 elif isinstance(self, NamespaceModule):
1171 if (self.namespace() == namespace):
1172 rv = 'Namespace'
1173 else:
1174 rv = 'pyxb.namespace.NamespaceForURI(%s)' % (repr(namespace.uri()),)
1175 '''
1176 namespace_module = self.ForNamespace(namespace)
1177 if namespace_module is not None:
1178 self._importModule(namespace_module)
1179 rv = '%s.Namespace' % (namespace_module.modulePath(),)
1180 else:
1181 assert False, 'Unexpected reference to %s' % (namespace,)
1182 #rv = 'pyxb.namespace.NamespaceForURI(%s)' % (repr(namespace.uri()),)
1183 '''
1184 else:
1185 if namespace.prefix():
1186 nsn = 'Namespace_%s' % (namespace.prefix(),)
1187 else:
1188 nsn = 'Namespace'
1189 for im in self.__importedModules:
1190 if isinstance(im, NamespaceModule) and (im.namespace() == namespace):
1191 rv = '%s.Namespace' % (im.modulePath(),)
1192 break
1193 if isinstance(im, NamespaceGroupModule):
1194 irv = im.__referencedNamespaces.get(namespace)
1195 if irv is not None:
1196 rv = self.defineNamespace(namespace, nsn, '%s.%s' % (im.modulePath(), irv), protected=True)
1197 break
1198 if rv is None:
1199 rv = self.defineNamespace(namespace, nsn, protected=True)
1200 assert 0 < len(self.__namespaceDeclarations)
1201 self.__referencedNamespaces[namespace] = rv
1202 return rv
1203
1205 return self.__bindingIO.literal(*args, **kw)
1206
1220
1228
1231 """This class represents a Python module that holds all the
1232 declarations belonging to a specific namespace."""
1233
1236 __namespace = None
1237
1240 __moduleRecord = None
1241
1246 __namespaceGroupModule = None
1247
1248 _UniqueInModule = _ModuleNaming_mixin._UniqueInModule.copy()
1249 _UniqueInModule.update([ 'Namespace', 'CreateFromDOM', 'CreateFromDocument' ])
1250
1253 __namespaceGroupHead = None
1254 __namespaceGroup = None
1255
1258 __components = None
1259
1260 @classmethod
1263 __ComponentModuleMap = { }
1264
1267
1269 ns = self.namespace()
1270 rvl = ['# Namespace %s' % (ns,)]
1271 if ns.prefix() is not None:
1272 rvl.append(' [xmlns:%s]' % (ns.prefix(),))
1273 rvl.append('\n')
1274 return ''.join(rvl)
1275
1280
1283
1284 - def __init__ (self, generator, module_record, mr_scc, components=None, **kw):
1301
1309
1310 - def _finalizeModuleContents_vx (self, template_map):
1311 self.bindingIO().prolog().append(self.bindingIO().expand('''
1312 import pyxb
1313 import pyxb.binding
1314 import pyxb.binding.saxer
1315 import StringIO
1316 import pyxb.utils.utility
1317 import pyxb.utils.domutils
1318 import sys
1319
1320 # Unique identifier for bindings created at the same time
1321 _GenerationUID = %{generation_uid_expr}
1322
1323 # Import bindings for namespaces imported into schema
1324 %{aux_imports}
1325
1326 %{namespace_decls}
1327 ModuleRecord = Namespace.lookupModuleRecordByUID(_GenerationUID, create_if_missing=True)
1328 ModuleRecord._setModule(sys.modules[__name__])
1329
1330 def CreateFromDocument (xml_text, default_namespace=None, location_base=None):
1331 """Parse the given XML and use the document element to create a Python instance."""
1332 if pyxb.XMLStyle_saxer != pyxb._XMLStyle:
1333 dom = pyxb.utils.domutils.StringToDOM(xml_text)
1334 return CreateFromDOM(dom.documentElement)
1335 saxer = pyxb.binding.saxer.make_parser(fallback_namespace=Namespace.fallbackNamespace(), location_base=location_base)
1336 handler = saxer.getContentHandler()
1337 saxer.parse(StringIO.StringIO(xml_text))
1338 instance = handler.rootObject()
1339 return instance
1340
1341 def CreateFromDOM (node, default_namespace=None):
1342 """Create a Python instance from the given DOM node.
1343 The node tag must correspond to an element declaration in this module.
1344
1345 @deprecated: Forcing use of DOM interface is unnecessary; use L{CreateFromDocument}."""
1346 if default_namespace is None:
1347 default_namespace = Namespace.fallbackNamespace()
1348 return pyxb.binding.basis.element.AnyCreateFromDOM(node, _fallback_namespace=default_namespace)
1349
1350 ''', **template_map))
1351
1352 __components = None
1353 __componentBindingName = None
1354
1364
1367
1437
1438
1439 -def GeneratePython (schema_location=None,
1440 schema_text=None,
1441 namespace=None,
1442 module_prefix_elts=[],
1443 **kw):
1454
1455 import optparse
1456 import re
1459 """Configuration and data for a single binding-generation action."""
1460
1461 _DEFAULT_bindingRoot = '.'
1463 """The directory path into which generated bindings will be written.
1464 @rtype: C{str}"""
1465 return self.__bindingRoot
1469 __bindingRoot = None
1470
1472 if isinstance(module_elts, basestring):
1473 module_elts = module_elts.split('.')
1474 else:
1475 module_elts = module_elts[:]
1476 assert 0 < len(module_elts)
1477 if not inhibit_extension:
1478 assert not module_elts[-1].endswith('.py')
1479 module_elts[-1] = '%s.py' % (module_elts[-1],)
1480 return os.path.join(self.bindingRoot(), *module_elts)
1481
1484 __generateToFiles = None
1485
1487
1488
1489
1490
1491 module_path = None
1492 if isinstance(module, NamespaceModule):
1493 mr = module.moduleRecord()
1494 if mr is None:
1495 return ('/dev/null', None, None)
1496 if self.generationUID() != mr.generationUID():
1497 return ('/dev/null', None, None)
1498 if not self.generateToFiles():
1499 return ('/dev/null', None, None)
1500 if mr.namespace().isBuiltinNamespace() and (not self.allowBuiltinGeneration()):
1501 return ('/dev/null', None, None)
1502 module_path = mr.modulePath()
1503 assert module_path is not None, 'No path specified for module %s' % (mr,)
1504
1505
1506
1507 module_elts = module_path.split('.')
1508 if self.writeForCustomization():
1509 import_file_path = self.__moduleFilePath(module_elts)
1510 module_elts.insert(-1, 'raw')
1511 if not os.path.exists(import_file_path):
1512 raw_module_path = '.'.join(module_elts)
1513 pyxb.utils.utility.OpenOrCreate(import_file_path).write("from %s import *\n" % (raw_module_path,))
1514 binding_file_path = self.__moduleFilePath(module_elts)
1515 try:
1516 binding_file = pyxb.utils.utility.OpenOrCreate(binding_file_path, tag=module.moduleUID())
1517 except OSError, e:
1518 if errno.EEXIST == e.errno:
1519 raise pyxb.BindingGenerationError('Target file %s for module %s bindings exists with other content' % (binding_file_path, mr))
1520 raise
1521 elif isinstance(module, NamespaceGroupModule):
1522 if not self.generateToFiles():
1523 raise pyxb.BindingGenerationError('Generation of namespace groups requires generate-to-files')
1524 module_elts = []
1525 if self.modulePrefix():
1526 module_elts.extend(self.modulePrefix().split('.'))
1527 if self.writeForCustomization():
1528 module_elts.append('raw')
1529 in_use = set()
1530 while True:
1531 module_elts.append(pyxb.utils.utility.PrepareIdentifier('nsgroup', in_use, protected=True))
1532 try:
1533 binding_file_path = self.__moduleFilePath(module_elts)
1534 print 'Attempting group %s uid %s at %s' % (module, module.moduleUID(), binding_file_path)
1535 binding_file = pyxb.utils.utility.OpenOrCreate(binding_file_path, tag=module.moduleUID())
1536 break
1537 except OSError, e:
1538 if errno.EEXIST != e.errno:
1539 raise
1540 module_elts.pop()
1541 module_path = '.'.join(module_elts)
1542 else:
1543 assert False
1544 if self.generateToFiles():
1545 for n in range(len(module_elts)-1):
1546 sub_path = self.__moduleFilePath(module_elts[:1+n], inhibit_extension=True)
1547 init_path = os.path.join(sub_path, '__init__.py')
1548 if not os.path.exists(init_path):
1549 file(init_path, 'w')
1550 return (binding_file_path, binding_file, module_path)
1551
1553 """The directory from which entrypoint schemas specified as
1554 relative file paths will be read."""
1555 return self.__schemaRoot
1557 if not schema_root.endswith(os.sep):
1558 schema_root = schema_root + os.sep
1559 self.__schemaRoot = schema_root
1560 return self
1561 __schemaRoot = None
1562
1564 """Optional string that is stripped from the beginning of
1565 schemaLocation values before loading from them.
1566
1567 This applies only to the values of schemaLocation attributes
1568 in C{import} and C{include} elements. Its purpose is to
1569 convert absolute schema locations into relative ones to allow
1570 offline processing when all schema are available in a local
1571 directory. See C{schemaRoot}.
1572 """
1573 return self.__schemaStrippedPrefix
1577 __schemaStrippedPrefix = None
1578
1580 """Optional map to rewrite schema locations.
1581
1582 This applies only to the values of schemaLocation attributes
1583 in C{import} and C{include} elements. Its purpose is to
1584 convert remote or absolute schema locations into local or
1585 relative ones to allow offline processing when all schema are
1586 available in a local directory. See C{schemaRoot}.
1587 """
1588 return self.__locationPrefixRewriteMap
1595 """Add a rewrite entry for schema locations.
1596
1597 @param prefix : A text prefix that should be removed from
1598 schema location URIs.
1599
1600 @param substituent : The text prefix that should replace
1601 C{prefix} as a prefix in a schema location URI.
1602 """
1603
1604 self.__locationPrefixRewriteMap[prefix] = substituent
1605 return self
1607 """Add a rewrite entry for schema locations.
1608
1609 Parameter values are strings of the form C{pfx=sub}. The
1610 effect is that a schema location that begins with C{pfx} is
1611 rewritten so that it instead begins with C{sub}."""
1612 try:
1613 (prefix, substituent) = prefix_rewrite.split('=', 1)
1614 except:
1615 raise
1616 self.addLocationPrefixRewrite(prefix, substituent)
1617 __locationPrefixMap = {}
1618
1620 """A list of locations from which entrypoint schemas are to be
1621 read.
1622
1623 The values in the list are either URIs, or tuples consisting
1624 of a value and a callable which, when passed the generator
1625 object and the value, will return a
1626 L{pyxb.xmlschema.structures.Schema} instance. See
1627 L{addSchemaLocation}.
1628
1629 See also L{addSchemaLocation} and L{schemas}.
1630 """
1631 return self.__schemaLocationList
1637 """Add the location of an entrypoint schema.
1638
1639 @param schema_location: The location of the schema. This
1640 should be a URL; if the schema location does not have a URL
1641 scheme (e.g., C{http:}), it is assumed to be a file, and if it
1642 is not an absolute path is located relative to the
1643 C{schemaRoot}.
1644
1645 @keyword converter: Optional callable that will be invoked
1646 with the generator instance and the schema location, and is
1647 expected to return a L{pyxb.xmlschema.structures.Schema}
1648 instance. If absent, the contents of the location are
1649 converted directly.
1650
1651 @note: The C{converter} argument derives from WSDL support: we
1652 need to add to the sequence of schema locations a URI of
1653 something that will not parse as a schema, but does have inner
1654 material that can if treated properly. "Treated properly" may
1655 include having the archive path and other namespace
1656 manipulations configured before anything is done to it.
1657 """
1658 self.__schemaLocationList.append( (schema_location, converter) )
1659 return self
1661 """Add the location of an entrypoint schema. The provided
1662 value should be a URL; if it does not have a URL scheme (e.g.,
1663 C{http:}), it is assumed to be a file, and if it is not an
1664 absolute path is located relative to the C{schemaRoot}."""
1665 self.addSchemaLocation(schema_location)
1666 __schemaLocationList = None
1667
1669 """Schema for which bindings should be generated.
1670
1671 These may be L{Schema<pyxb.xmlschema.structures.Schema>}
1672 instances, or strings; the latter is preferred, and is parsed
1673 into a Schema instance when required.
1674
1675 This is the list of entrypoint schemas for binding generation.
1676 Values in L{schemaLocationList} are read and converted into
1677 schema, then appended to this list. Values from L{moduleList}
1678 are applied starting with the first schema in this list.
1679 """
1680 return self.__schemas[:]
1688 __schemas = None
1689
1691 """The set of L{namespaces<pyxb.namespace.Namespace>} for
1692 which bindings will be generated.
1693
1694 This is the set of namespaces read from entrypoint schema,
1695 closed under reference to namespaces defined by schema import.
1696
1697 @rtype: C{set}
1698 """
1699 return self.__namespaces.copy()
1707 __namespaces = None
1708
1710 """A list of module names to be applied in order to the namespaces of entrypoint schemas"""
1711 return self.__moduleList[:]
1716
1718 """Add a module name corresponding to an entrypoint schema.
1719
1720 The namespace defined by the corresponding schema will be
1721 written to a binding using the given module name, adjusted by
1722 L{modulePrefix}."""
1723 self.__moduleList.append(module_name)
1724 return self
1725 __moduleList = None
1726
1728 """The prefix for binding modules.
1729
1730 The base name for the module holding a binding is taken from
1731 the moduleList, moduleMap, or an XMLNS prefix associated with
1732 the namespace in a containing schema. This value, if present,
1733 is used as a prefix to allow a deeper module hierarchy."""
1734 return self.__modulePrefix
1738 __modulePrefix = None
1739
1741 """A map from namespace URIs to the module to be used for the
1742 corresponding generated binding.
1743
1744 Module values are adjusted by L{modulePrefix} if that has been
1745 specified.
1746
1747 An entry in this map for a namespace supersedes the module
1748 specified in moduleList if the namespace is defined by an
1749 entrypoint schema.
1750
1751 @return: A reference to the namespace module map.
1752 """
1753 return self.__namespaceModuleMap
1754 __namespaceModuleMap = None
1755
1757 """A colon-separated list of paths from which namespace
1758 archives can be read.
1759
1760 The default path is the contents of the C{PYXB_ARCHIVE_PATH}
1761 environment variable, or the standard path configured at
1762 installation time. Any file with the extension C{.wxs} found
1763 in one of these directories is examined to see whether it is a
1764 namespace archive.
1765 """
1766 return self.__archivePath
1770 __archivePath = None
1771
1773 """A frozenset of namespaces that many not be loaded from an archive."""
1774 return frozenset(self.__noLoadNamespaces)
1776 """Record the set of namespaces that should not be loaded from an archive.
1777
1778 The expectation is that any required entities in the namespace
1779 will be defined by loading schema."""
1780 self.__noLoadNamespaces.clear()
1781 self.__noLoadNamespaces.update([ pyxb.namespace.NamespaceInstance(_ns) for _ns in namespace_set ])
1783 """Mark that the specified namespace should not be loaded from an archive.
1784
1785 Use this when you are generating bindings for an application
1786 that has a restricted profile of a namespace that would
1787 otherwise be read from an archive. Be aware that this removes
1788 any knowledge of any archive in which this namespace is
1789 present as a non-private member."""
1790 self.__noLoadNamespaces.add(pyxb.namespace.NamespaceInstance(namespace))
1791 __noloadNamespaces = None
1792
1794 """A list of paths to archives that should be loaded, in order, prior to parsing schema."""
1795 return frozenset(self.__preLoadArchives)
1797 """Name of a file containing a stored archive from which
1798 namespaces should be read prior to processing schema.
1799
1800 Files to be pre-loaded are not affected by
1801 C{noLoadNamespace}."""
1802 self.__preLoadArchives.append(archive_file)
1806 __preLoadArchives = None
1807
1809 """Optional file into which the archive of namespaces will be written.
1810
1811 Subsequent generation actions can read pre-parsed namespaces
1812 from this file, and therefore reference the bindings that were
1813 built earlier rather than re-generating them.
1814
1815 The file name should normally end with C{.wxs}."""
1816 return self.__archiveToFile
1820 __archiveToFile = None
1821
1835 """Indicates, for specific namespaces, whether their
1836 visibility in the archive should be public or private."""
1837 return self.__namespaceVisibilityMap.copy()
1838 __namespaceVisibilityMap = None
1839
1841 """Indicates whether unmentioned namespaces will be public or private (default) in the archive.
1842
1843 A namespace is I{mentioned} if it is the target namespace of
1844 an entrypoint schema, or appears in a namespace visibility
1845 specification. I.e., this default applies only to namespaces
1846 that are modified as a result of including some schema, which
1847 is generally a local customization of something.
1848 """
1849 return self.__defaultNamespacePublic
1852 __defaultNamespacePublic = None
1853
1855 """Indicates whether the bindings should validate mutations
1856 against the content model."""
1857 return self.__validateChanges
1862 __validateChanges = None
1863
1864 _DEFAULT_bindingStyle = basis.CURRENT_BINDING_STYLE
1866 """The style of Python used in generated bindings.
1867
1868 C{accessor} means values are private variables accessed
1869 through inspector and mutator methods.
1870
1871 C{property} means values are private variables accessed
1872 through a Python property.
1873 """
1874 return self.__bindingStyle
1879 __bindingStyle = None
1880
1882 """Indicates whether the binding Python code should be written into a sub-module for customization.
1883
1884 If enabled, a module C{path.to.namespace} will be written to
1885 the file C{path/to/raw/namespace.py}, so that the file
1886 C{path/to/namespace.py} can import it and override behavior."""
1887 return self.__writeForCustomization
1891 __writeForCustomization = None
1892
1894 """Indicates whether the code generator is permitted to
1895 process namespace for which no module path can be determined.
1896
1897 Use this only when generating bindings that will not be
1898 referenced by other bindings."""
1899 return self.__allowAbsentModule
1903 __allowAbsentModule = None
1904
1906 """Indicates whether bindings will be written for namespaces that are built-in to PyXB.
1907
1908 This must be enabled when building bindings for the XML,
1909 XMLSchema instance, and other built-in namespaces. Normally
1910 generation of these namespaces is inhibited lest it produce
1911 inconsistencies."""
1912 return self.__allowBuiltinGeneration
1916 __allowBuiltinGeneration = None
1917
1919 """The directory path into which any content retrieved by URI will be written.
1920
1921 This serves as a local cache, and to give you an opportunity
1922 to inspect material retrieved from some other system.
1923 @rtype: C{str}"""
1924 return self.__uriContentArchiveDirectory
1927 __uriContentArchiveDirectory = None
1928
1930 """Create a configuration to be used for generating bindings.
1931
1932 Arguments are treated as additions to the schema location list
1933 after all keywords have been processed.
1934
1935 @keyword binding_root: Invokes L{setBindingRoot}
1936 @keyword schema_root: Invokes L{setSchemaRoot}
1937 @keyword schema_stripped_prefix: Invokes L{setSchemaStrippedPrefix}
1938 @keyword location_prefix_rewrite_map: Invokes L{setLocationPrefixRewriteMap}
1939 @keyword schema_location_list: Invokes L{setSchemaLocationList}
1940 @keyword module_list: Invokes L{_setModuleList}
1941 @keyword module_prefix: Invokes L{setModulePrefix}
1942 @keyword archive_path: Invokes L{setArchivePath}
1943 @keyword no_load_namespaces: Invokes L{_setNoLoadNamespaces}
1944 @keyword pre_load_archives: Invokes L{_setPreLoadArchives}
1945 @keyword archive_to_file: Invokes L{setArchiveToFile}
1946 @keyword public_namespace: Invokes L{setNamespaceVisibility}
1947 @keyword private_namespace: Invokes L{setNamespaceVisibility}
1948 @keyword default_namespace_public: Invokes L{setDefaultNamespacePublic}
1949 @keyword validate_changes: Invokes L{setValidateChanges}
1950 @keyword binding_style: Invokes L{setBindingStyle}
1951 @keyword namespace_module_map: Initializes L{namespaceModuleMap}
1952 @keyword schemas: Invokes L{setSchemas}
1953 @keyword namespaces: Invokes L{setNamespaces}
1954 @keyword write_for_customization: Invokes L{setWriteForCustomization}
1955 @keyword allow_builtin_generation: Invokes L{setAllowBuiltinGeneration}
1956 @keyword allow_absent_module: Invokes L{setAllowAbsentModule}
1957 @keyword generate_to_files: Sets L{generateToFiles}
1958 @keyword uri_content_archive_directory: Invokes L{setUriContentArchiveDirectory}
1959 """
1960 argv = kw.get('argv', None)
1961 if argv is not None:
1962 kw = {}
1963 self.__bindingRoot = kw.get('binding_root', self._DEFAULT_bindingRoot)
1964 self.__schemaRoot = kw.get('schema_root', '.')
1965 self.__schemaStrippedPrefix = kw.get('schema_stripped_prefix')
1966 self.__locationPrefixRewriteMap = kw.get('location_prefix_rewrite_map', {})
1967 self.__schemas = []
1968 self.__schemaLocationList = kw.get('schema_location_list', [])[:]
1969 self.__moduleList = kw.get('module_list', [])[:]
1970 self.__modulePrefix = kw.get('module_prefix')
1971 self.__archivePath = kw.get('archive_path', pyxb.namespace.archive.GetArchivePath())
1972 self.__noLoadNamespaces = kw.get('no_load_namespaces', set()).copy()
1973 self.__preLoadArchives = kw.get('pre_load_archives', [])[:]
1974 self.__archiveToFile = kw.get('archive_to_file')
1975 self.__namespaceVisibilityMap = {}
1976 self._setNamespaceVisibilities(kw.get('public_namespaces', set()), kw.get('private_namespaces', set()))
1977 self.__defaultNamespacePublic = kw.get('default_namespace_public', False)
1978 self.__validateChanges = kw.get('validate_changes', True)
1979 self.__bindingStyle = kw.get('binding_style', self._DEFAULT_bindingStyle)
1980 self.__namespaceModuleMap = kw.get('namespace_module_map', {}).copy()
1981 self.__schemas = kw.get('schemas', [])[:]
1982 self.__namespaces = set(kw.get('namespaces', []))
1983 self.__writeForCustomization = kw.get('write_for_customization', False)
1984 self.__writeForCustomization = kw.get('allow_builtin_generation', False)
1985 self.__allowAbsentModule = kw.get('allow_absent_module', False)
1986 self.__generateToFiles = kw.get('generate_to_files', True)
1987 self.__uriContentArchiveDirectory = kw.get('uri_content_archive_directory')
1988
1989 if argv is not None:
1990 self.applyOptionValues(*self.optionParser().parse_args(argv))
1991 [ self.addSchemaLocation(_a) for _a in args ]
1992
1993 self.__generationUID = pyxb.utils.utility.UniqueIdentifier()
1994
1995 pyxb.namespace.XML.validateComponentModel()
1996
1997 __stripSpaces_re = re.compile('\s\s\s+')
2000
2001 __OptionSetters = (
2002 ('binding_root', setBindingRoot),
2003 ('schema_root', setSchemaRoot),
2004 ('schema_stripped_prefix', setSchemaStrippedPrefix),
2005 ('location_prefix_rewrite', argAddLocationPrefixRewrite),
2006 ('schema_location', setSchemaLocationList),
2007 ('module', _setModuleList),
2008 ('module_prefix', setModulePrefix),
2009 ('archive_path', setArchivePath),
2010 ('no_load_namespace', _setNoLoadNamespaces),
2011 ('pre_load_archive', _setPreLoadArchives),
2012 ('archive_to_file', setArchiveToFile),
2013 ('default_namespace_public', setDefaultNamespacePublic),
2014 ('binding_style', setBindingStyle),
2015 ('validate_changes', setValidateChanges),
2016 ('write_for_customization', setWriteForCustomization),
2017 ('allow_builtin_generation', setAllowBuiltinGeneration),
2018 ('allow_absent_module', setAllowAbsentModule),
2019 ('uri_content_archive_directory', setUriContentArchiveDirectory)
2020 )
2032
2034 if argv is None:
2035 argv = sys.argv[1:]
2036 (options, args) = self.optionParser().parse_args(argv)
2037 self.applyOptionValues(options, args)
2038 return self
2039
2042 __generationUID = None
2043
2045 """Return an C{optparse.OptionParser} instance tied to this configuration.
2046
2047 @param reset: If C{False} (default), a parser created in a
2048 previous invocation will be returned. If C{True}, any
2049 previous option parser is discarded and a new one created.
2050 @type reset: C{bool}
2051 """
2052 if reset or (self.__optionParser is None):
2053 parser = optparse.OptionParser(usage="%prog [options] [more schema locations...]",
2054 version='%%prog from PyXB %s' % (pyxb.__version__,),
2055 description='Generate bindings from a set of XML schemas')
2056
2057 group = optparse.OptionGroup(parser, 'Identifying Schema', 'Specify and locate schema for which bindings should be generated.')
2058 group.add_option('--schema-location', '-u', metavar="FILE_or_URL",
2059 action='append',
2060 help=self.__stripSpaces(self.argAddSchemaLocation.__doc__))
2061 group.add_option('--schema-root', metavar="DIRECTORY",
2062 help=self.__stripSpaces(self.schemaRoot.__doc__))
2063 group.add_option('--schema-stripped-prefix', metavar="TEXT", type='string',
2064 help=self.__stripSpaces(self.schemaStrippedPrefix.__doc__))
2065 group.add_option('--location-prefix-rewrite', metavar="TEXT", type='string',
2066 help=self.__stripSpaces(self.argAddLocationPrefixRewrite.__doc__))
2067 group.add_option('--uri-content-archive-directory', metavar="DIRECTORY",
2068 help=self.__stripSpaces(self.uriContentArchiveDirectory.__doc__))
2069 parser.add_option_group(group)
2070
2071 group = optparse.OptionGroup(parser, 'Configuring Bindings', 'Specify where generated bindings should be written, and how they will be accessed from Python.')
2072 group.add_option('--module', '-m', metavar="MODULE",
2073 action='append',
2074 help=self.__stripSpaces(self.addModuleName.__doc__))
2075 group.add_option('--module-prefix', metavar="MODULE",
2076 help=self.__stripSpaces(self.modulePrefix.__doc__))
2077 group.add_option('--binding-root', metavar="DIRECTORY",
2078 help=self.__stripSpaces(self.bindingRoot.__doc__))
2079 group.add_option('-r', '--write-for-customization',
2080 action='store_true', dest='write_for_customization',
2081 help=self.__stripSpaces(self.writeForCustomization.__doc__ + ' This option turns on the feature.'))
2082 group.add_option('--no-write-for-customization',
2083 action='store_false', dest='write_for_customization',
2084 help=self.__stripSpaces(self.writeForCustomization.__doc__ + ' This option turns off the feature (I{default}).'))
2085 parser.add_option_group(group)
2086
2087 group = optparse.OptionGroup(parser, 'Reading Namespace Archives', 'Locating and loading (or inhibiting load of) namespace archives.')
2088 group.add_option('--archive-path', metavar="PATH",
2089 help=self.__stripSpaces(self.archivePath.__doc__))
2090 group.add_option('--pre-load-archive', metavar="FILE",
2091 action='append',
2092 help=self.__stripSpaces(self.addPreLoadArchive.__doc__))
2093 group.add_option('--no-load-namespace', metavar="URI",
2094 action='append',
2095 help=self.__stripSpaces(self.addNoLoadNamespace.__doc__))
2096 parser.add_option_group(group)
2097
2098 group = optparse.OptionGroup(parser, 'Writing Namespace Archives', 'Control the location and content of a namespace archive corresponding to a binding generation.')
2099 group.add_option('--archive-to-file', metavar="FILE",
2100 help=self.__stripSpaces(self.archiveToFile.__doc__))
2101 group.add_option('--public-namespace', metavar="URI",
2102 action='append',
2103 help=self.__stripSpaces(self.namespaceVisibilityMap.__doc__ + ' This option adds the namespace as a public archive member.'))
2104 group.add_option('--private-namespace', metavar="URI",
2105 action='append',
2106 help=self.__stripSpaces(self.namespaceVisibilityMap.__doc__ + ' This option adds the namespace as a private archive member.'))
2107 group.add_option('--default-namespace-public',
2108 action="store_true", dest='default_namespace_public',
2109 help=self.__stripSpaces(self.defaultNamespacePublic.__doc__ + ' This option makes the default C{public} (I{default}).'))
2110 group.add_option('--default-namespace-private',
2111 action="store_false", dest='default_namespace_public',
2112 help=self.__stripSpaces(self.defaultNamespacePublic.__doc__ + ' This option makes the default C{private}.'))
2113 parser.add_option_group(group)
2114
2115 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.")
2116 group.add_option('--binding-style',
2117 type='choice', choices=basis.BINDING_STYLES,
2118 help=self.__stripSpaces(self.bindingStyle.__doc__))
2119 group.add_option('--validate-changes',
2120 action='store_true', dest='validate_changes',
2121 help=self.__stripSpaces(self.validateChanges.__doc__ + ' This option turns on validation (default).'))
2122 group.add_option('--no-validate-changes',
2123 action='store_false', dest='validate_changes',
2124 help=self.__stripSpaces(self.validateChanges.__doc__ + ' This option turns off validation.'))
2125 parser.add_option_group(group)
2126
2127 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.")
2128 group.add_option('--allow-absent-module',
2129 action='store_true', dest='allow_absent_module',
2130 help=self.__stripSpaces(self.allowAbsentModule.__doc__ + ' This option turns on the feature.'))
2131 group.add_option('--no-allow-absent-module',
2132 action='store_false', dest='allow_absent_module',
2133 help=self.__stripSpaces(self.allowAbsentModule.__doc__ + ' This option turns off the feature (default).'))
2134 group.add_option('--allow-builtin-generation',
2135 action='store_true', dest='allow_builtin_generation',
2136 help=self.__stripSpaces(self.allowBuiltinGeneration.__doc__ + ' This option turns on the feature.'))
2137 group.add_option('--no-allow-builtin-generation',
2138 action='store_false', dest='allow_builtin_generation',
2139 help=self.__stripSpaces(self.allowBuiltinGeneration.__doc__ + ' This option turns off the feature (default).'))
2140 parser.add_option_group(group)
2141
2142 self.__optionParser = parser
2143 return self.__optionParser
2144 __optionParser = None
2145
2147 """Return a command line option sequence that could be used to
2148 construct an equivalent configuration.
2149
2150 @note: If you extend the option parser, as is done by
2151 C{pyxbgen}, this may not be able to reconstruct the correct
2152 command line."""
2153 opts = []
2154 module_list = self.moduleList()
2155 schema_list = self.schemaLocationList()
2156 while module_list and schema_list:
2157 ml = module_list.pop(0)
2158 sl = schema_list.pop(0)
2159 if isinstance(sl, tuple):
2160 sl = sl[0]
2161 opts.extend(['--schema-location=' + sl, '--module=' + ml])
2162 for sl in schema_list:
2163 opts.append('--schema-location=' + sl)
2164 if self.schemaRoot() is not None:
2165 opts.append('--schema-root=' + self.schemaRoot())
2166 if self.schemaStrippedPrefix() is not None:
2167 opts.append('--schema-stripped-prefix=%s' + self.schemaStrippedPrefix())
2168 for (pfx, sub) in self.locationPrefixRewriteMap():
2169 opts.append('--location-prefix-rewrite=%s=%s' % (pfx, sub))
2170 if self.modulePrefix() is not None:
2171 opts.append('--module-prefix=' + self.modulePrefix())
2172 opts.append('--binding-root=' + self.bindingRoot())
2173 if self.archivePath() is not None:
2174 opts.append('--archive-path=' + self.archivePath())
2175 for ns in self.noLoadNamespaces():
2176 opts.append('--no-load-namespace=' + ns.uri())
2177 for fps in self.preLoadArchives():
2178 opts.append('--pre-load-archive=' + fp)
2179 if self.archiveToFile() is not None:
2180 opts.append('--archive-to-file=' + self.archiveToFile())
2181 for (ns, visibility) in self._namespaceVisibilityMap():
2182 if visibility:
2183 opts.append('--public-namespace=' + ns.uri())
2184 else:
2185 opts.append('--private-namespace=' + ns.uri())
2186 if self.defaultNamespacePublic():
2187 opts.append('--default-namespace-public')
2188 else:
2189 opts.append('--default-namespace-private')
2190 for (val, opt) in ( (self.validateChanges(), 'validate-changes'),
2191 (self.writeForCustomization(), 'write-for-customization'),
2192 (self.allowAbsentModule(), 'allow-absent-module'),
2193 (self.allowBuiltinGeneration(), 'allow-builtin-generation') ):
2194 if val:
2195 opts.append('--' + opt)
2196 else:
2197 opts.append('--no-' + opt)
2198 if self.uriContentArchiveDirectory() is not None:
2199 opts.append('--uri-content-archive-directory=%s' + self.uriContentArchiveDirectory())
2200 return opts
2201
2207
2222
2223 __didResolveExternalSchema = False
2225 if self.__didResolveExternalSchema and (not reset):
2226 raise pyxb.PyXBException('Cannot resolve external schema multiple times')
2227
2228 required_archives = pyxb.namespace.archive.NamespaceArchive.PreLoadArchives(self.archivePath(), self.preLoadArchives())
2229 for nsa in required_archives:
2230 nsa.readNamespaces()
2231 for ns in self.noLoadNamespaces():
2232 assert isinstance(ns, pyxb.namespace.Namespace)
2233 ns.markNotLoadable()
2234 while self.__schemaLocationList:
2235 sl = self.__schemaLocationList.pop(0)
2236 if isinstance(sl, tuple):
2237 (sl, converter) = sl
2238 else:
2239 converter = None
2240 try:
2241 if converter is None:
2242 schema = xs.schema.CreateFromLocation(absolute_schema_location=self.normalizeSchemaLocation(sl),
2243 generation_uid=self.generationUID(),
2244 uri_content_archive_directory=self.uriContentArchiveDirectory())
2245 else:
2246 schema = converter(self, sl)
2247 self.addSchema(schema)
2248 except pyxb.SchemaUniquenessError, e:
2249 print 'WARNING: Skipped redundant translation of %s defining %s' % (e.schemaLocation(), e.namespace())
2250 self.addSchema(e.existingSchema())
2251 for schema in self.__schemas:
2252 if isinstance(schema, basestring):
2253 schema = xs.schema.CreateFromDocument(schema, generation_uid=self.generationUID())
2254 origin = schema.originRecord()
2255 assert origin is not None
2256 module_path = None
2257 if self.__moduleList:
2258 module_path = self.__moduleList.pop(0)
2259 self.__assignModulePath(origin.moduleRecord(), module_path)
2260 assert schema.targetNamespace() == origin.moduleRecord().namespace()
2261 self.addNamespace(schema.targetNamespace())
2262 self.__didResolveExternalSchema = True
2263 self.__bindingModules = None
2264
2290
2292 named_bindable_fn = lambda _c: (isinstance(_c, xs.structures.ElementDeclaration) and _c._scopeIsGlobal()) or _c.isTypeDefinition()
2293 bindable_fn = lambda _c: isinstance(_c, xs.structures.ElementDeclaration) or _c.isTypeDefinition()
2294
2295 self.__moduleRecords = set()
2296 all_components = set()
2297 for origin in self.generationUID().associatedObjects():
2298 mr = origin.moduleRecord()
2299 if not (mr in self.__moduleRecords):
2300
2301
2302 self.__moduleRecords.add(mr)
2303 mr.completeGenerationAssociations()
2304 all_components.update(origin.originatedObjects())
2305
2306 namespaces = set()
2307 for mr in self.__moduleRecords:
2308 if mr.namespace().isBuiltinNamespace() and not self.allowBuiltinGeneration():
2309 continue
2310 namespaces.add(mr.namespace())
2311 pyxb.namespace.resolution.ResolveSiblingNamespaces(namespaces)
2312
2313
2314
2315 for ns in self.namespaces():
2316 self.__namespaceVisibilityMap.setdefault(ns, True)
2317
2318
2319
2320
2321 component_graph = self.__graphFromComponents(all_components, True)
2322
2323 binding_components = set(filter(bindable_fn, component_graph.nodes()))
2324
2325
2326
2327 module_graph = pyxb.utils.utility.Graph()
2328 [ module_graph.addRoot(_mr) for _mr in self.__moduleRecords ]
2329 for (s, t) in component_graph.edges():
2330 module_graph.addEdge(s._objectOrigin().moduleRecord(), t._objectOrigin().moduleRecord())
2331 module_scc_order = module_graph.sccOrder()
2332
2333
2334
2335
2336
2337
2338
2339
2340 for c in binding_components:
2341 assert bindable_fn(c), 'Unexpected %s in binding components' % (type(s),)
2342 c._setBindingNamespace(c._objectOrigin().moduleRecord().namespace())
2343
2344 record_binding_map = {}
2345 unique_in_bindings = set([NamespaceGroupModule._GroupPrefix])
2346 modules = []
2347 for mr_scc in module_scc_order:
2348 scc_modules = [ ]
2349 for mr in mr_scc:
2350
2351
2352 mr._setIsPublic(self.__namespaceVisibilityMap.get(mr.namespace(), self.defaultNamespacePublic()))
2353 self.__assignModulePath(mr)
2354 assert not ((mr.modulePath() is None) and self.generateToFiles()), 'No module path defined for %s' % (mr,)
2355 if (not mr.isPublic()) and (mr.modulePath() is not None):
2356 elts = mr.modulePath().split('.')
2357 elts[-1] = '_%s' % (elts[-1],)
2358 mr.setModulePath('.'.join(elts))
2359 nsm = NamespaceModule(self, mr, mr_scc)
2360 record_binding_map[mr] = nsm
2361 scc_modules.append(nsm)
2362
2363 modules.extend(scc_modules)
2364 if 1 < len(mr_scc):
2365 ngm = NamespaceGroupModule(self, scc_modules)
2366 modules.append(ngm)
2367 for nsm in scc_modules:
2368 nsm.setNamespaceGroupModule(ngm)
2369
2370 component_csets = self.__graphFromComponents(binding_components, False).sccOrder()
2371 bad_order = False
2372 component_order = []
2373 for cset in component_csets:
2374 if 1 < len(cset):
2375 print "COMPONENT DEPENDENCY LOOP of %d components" % (len(cset),)
2376 cg = pyxb.utils.utility.Graph()
2377 for c in cset:
2378 assert bindable_fn(c), 'Unexpected %s in list' % (type(c),)
2379 print ' %s' % (c.expandedName(),)
2380 cg.addNode(c)
2381 for cd in c.bindingRequires(reset=True, include_lax=False):
2382
2383 cg.addEdge(c, cd)
2384
2385 relaxed_order = cg.sccOrder()
2386 for rcs in relaxed_order:
2387 assert 1 == len(rcs)
2388 rcs = rcs[0]
2389 if rcs in cset:
2390 component_order.append(rcs)
2391 else:
2392 component_order.extend(cset)
2393
2394
2395
2396 element_declarations = []
2397 type_definitions = []
2398 for c in component_order:
2399 if isinstance(c, xs.structures.ElementDeclaration) and c._scopeIsGlobal():
2400
2401 nsm = record_binding_map[c._objectOrigin().moduleRecord()]
2402 nsm.bindComponent(c)
2403 element_declarations.append(c)
2404 elif c.isTypeDefinition():
2405 type_definitions.append(c)
2406 else:
2407
2408 pass
2409
2410 simple_type_definitions = []
2411 complex_type_definitions = []
2412 for td in type_definitions:
2413 nsm = record_binding_map[td._objectOrigin().moduleRecord()]
2414 assert nsm is not None, 'No namespace module for %s type %s scope %s namespace %s' % (td.expandedName(), type(td), td._scope(), td.bindingNamespace)
2415 module_context = nsm.bindComponent(td)
2416 assert isinstance(module_context, _ModuleNaming_mixin), 'Unexpected type %s' % (type(module_context),)
2417 if isinstance(td, xs.structures.SimpleTypeDefinition):
2418 _PrepareSimpleTypeDefinition(td, self, nsm, module_context)
2419 simple_type_definitions.append(td)
2420 elif isinstance(td, xs.structures.ComplexTypeDefinition):
2421 _PrepareComplexTypeDefinition(td, self, nsm, module_context)
2422 complex_type_definitions.append(td)
2423 else:
2424 assert False, 'Unexpected component type %s' % (type(td),)
2425
2426 for ngm in modules:
2427 if isinstance(ngm, NamespaceGroupModule):
2428 for m in ngm.namespaceModules():
2429 m.addImportsFrom(ngm)
2430
2431 for std in simple_type_definitions:
2432 GenerateSTD(std, self)
2433 for ctd in complex_type_definitions:
2434 GenerateCTD(ctd, self)
2435 for ed in element_declarations:
2436 GenerateED(ed, self)
2437
2438 return modules
2439
2440 __bindingModules = None
2447
2449 archive_file = self.archiveToFile()
2450 if archive_file is not None:
2451 ns_archive = pyxb.namespace.archive.NamespaceArchive(generation_uid=self.generationUID())
2452 try:
2453 ns_archive.writeNamespaces(pyxb.utils.utility.OpenOrCreate(archive_file))
2454 print 'Saved parsed schema to %s URI' % (archive_file,)
2455 except Exception, e:
2456 print 'Exception saving preprocessed schema to %s: %s' % (archive_file, e)
2457 traceback.print_exception(*sys.exc_info())
2458
2459
2460
2461
2462 if isinstance(e, (AssertionError, AttributeError, TypeError)):
2463 raise
2464
2467