1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """The really ugly code that generates the Python bindings. This
17 whole thing is going to be refactored once customized generation makes
18 it to the top of the task queue."""
19
20 import pyxb
21 import pyxb.xmlschema as xs
22 import StringIO
23 import datetime
24 import errno
25
26 from pyxb.utils import utility
27 from pyxb.utils import templates
28 from pyxb.binding import basis
29 from pyxb.binding import datatypes
30 from pyxb.binding import facets
31
32 import types
33 import sys
34 import traceback
35 import os.path
36 import logging
37 import logging.config
38
39 _log = logging.getLogger(__name__)
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
144
152
160
162 enumerationElement = None
163
165
166
167
168
169
170
171
172
173 value = kw.get('enum_value', None)
174 assert (value is None) or isinstance(value, facets._Enumeration_mixin)
175
176
177
178 facet_instance = kw.get('facet_instance', None)
179 if facet_instance is None:
180 assert isinstance(value, facets._Enumeration_mixin)
181 facet_instance = value._CF_enumeration
182 assert isinstance(facet_instance, facets.CF_enumeration)
183
184
185
186 self.enumerationElement = kw.get('enumeration_element', None)
187 if self.enumerationElement is None:
188 assert value is not None
189 self.enumerationElement = facet_instance.elementForValue(value)
190 assert isinstance(self.enumerationElement, facets._EnumerationElement)
191 assert self.enumerationElement.tag() is not None
192
193
194
195 kw.setdefault('type_definition', facet_instance.valueDatatype())
196
197 super(ReferenceEnumerationMember, self).__init__(**kw)
198
199 self.setLiteral(self._addTypePrefix(self.enumerationElement.tag(), **kw))
200
202
203 if isinstance(value, types.DictionaryType):
204 return ', '.join([ '%s=%s' % (k, pythonLiteral(v, **kw)) for (k, v) in value.items() ])
205
206
207 if isinstance(value, types.ListType):
208 return [ pythonLiteral(_v, **kw) for _v in value ]
209
210
211 if isinstance(value, pyxb.namespace.ExpandedName):
212 return pythonLiteral(ReferenceExpandedName(expanded_name=value, **kw))
213
214
215 if isinstance(value, (types.TupleType, set)):
216 return type(value)(pythonLiteral(list(value), **kw))
217
218
219
220 if isinstance(value, facets._Enumeration_mixin):
221 return pythonLiteral(ReferenceEnumerationMember(enum_value=value, **kw))
222
223
224
225
226 if isinstance(value, basis.simpleTypeDefinition):
227 return PrefixModule(value, value.pythonLiteral())
228
229 if isinstance(value, pyxb.namespace.Namespace):
230 return pythonLiteral(ReferenceNamespace(namespace=value, **kw))
231
232 if isinstance(value, type):
233 if issubclass(value, basis.simpleTypeDefinition):
234 return PrefixModule(value)
235 if issubclass(value, facets.Facet):
236 return PrefixModule(value)
237
238
239 if isinstance(value, types.StringTypes):
240 return utility.QuotedEscaped(value,)
241
242 if isinstance(value, facets.Facet):
243 return pythonLiteral(ReferenceFacet(facet=value, **kw))
244
245
246 if isinstance(value, facets._PatternElement):
247 return pythonLiteral(value.pattern)
248
249
250 if isinstance(value, facets._EnumerationElement):
251 return pythonLiteral(value.value())
252
253
254 if isinstance(value, xs.structures.Wildcard):
255 return pythonLiteral(ReferenceWildcard(value, **kw))
256
257
258 if isinstance(value, xs.structures._SchemaComponent_mixin):
259 return pythonLiteral(ReferenceSchemaComponent(value, **kw))
260
261
262 if isinstance(value, ReferenceLiteral):
263 return value.asLiteral()
264
265
266 if isinstance(value, pyxb.namespace.Namespace):
267 return repr(value.uri())
268
269
270 if isinstance(value, (types.NoneType, types.BooleanType, types.FloatType, types.IntType, types.LongType)):
271 return repr(value)
272
273 raise Exception('Unexpected literal type %s' % (type(value),))
274
275
276 -def GenerateContentTerm (ctd, term, binding_module, **kw):
277 lines = []
278 padding = ' '
279 separator = ",\n%s" % (padding,)
280 template_map = { 'ctd' : binding_module.literal(ctd, **kw) }
281 if isinstance(term, xs.structures.Wildcard):
282 term_val = binding_module.literal(term, **kw)
283 elif isinstance(term, xs.structures.ElementDeclaration):
284 term_val = templates.replaceInText('%{ctd}._UseForTag(%{field_tag})', field_tag=binding_module.literal(term.expandedName(), **kw), **template_map)
285 else:
286 gm_id = utility.PrepareIdentifier('GroupModel', binding_module.uniqueInClass(ctd), protected=True)
287 assert isinstance(term, xs.structures.ModelGroup)
288 if (term.C_ALL == term.compositor()):
289 group_val = 'All'
290 elif (term.C_CHOICE == term.compositor()):
291 group_val = 'Choice'
292 else:
293 assert term.C_SEQUENCE == term.compositor()
294 group_val = 'Sequence'
295 pvalues = []
296 for p in term.particles():
297 (value, plines) = GenerateContentParticle(ctd, p, binding_module, **kw)
298 if plines:
299 lines.extend(plines)
300 pvalues.append(value)
301 group_val = "pyxb.binding.content.Group%s(\n" % (group_val,) + padding + separator.join(pvalues) + "\n" + padding + ")"
302 template_map['gm_id'] = gm_id
303 lines.append(templates.replaceInText('%{ctd}.%{gm_id} = %{group_val}', group_val=group_val, **template_map))
304 term_val = templates.replaceInText('%{ctd}.%{gm_id}', **template_map)
305 return (term_val, lines)
306
307 -def GenerateContentParticle (ctd, particle, binding_module, **kw):
308 template_map = { }
309 template_map['ctd'] = binding_module.literal(ctd, **kw)
310 template_map['min_occurs'] = repr(particle.minOccurs())
311 template_map['max_occurs'] = repr(particle.maxOccurs())
312 (term_val, lines) = GenerateContentTerm(ctd, particle.term(), binding_module, **kw)
313 particle_val = templates.replaceInText('pyxb.binding.content.ParticleModel(%{term_val}, min_occurs=%{min_occurs}, max_occurs=%{max_occurs})', term_val=term_val, **template_map)
314 return (particle_val, lines)
315
335
337 binding_module = kw['binding_module']
338 outf = binding_module.bindingIO()
339 facet_instances = []
340 gen_enum_tag = _useEnumerationTags(td)
341 for (fc, fi) in td.facets().items():
342
343
344 if (fi is None) and (fc in td.baseTypeDefinition().facets()):
345
346 continue
347 if (fi is not None) and (fi.ownerTypeDefinition() != td):
348
349 continue
350 argset = { }
351 is_collection = issubclass(fc, facets._CollectionFacet_mixin)
352 if issubclass(fc, facets._LateDatatype_mixin):
353 vdt = td
354 if fc.LateDatatypeBindsSuperclass():
355 vdt = vdt.baseTypeDefinition()
356 argset['value_datatype'] = vdt
357 if fi is not None:
358 if not is_collection:
359 argset['value'] = fi.value()
360 if isinstance(fi, facets.CF_enumeration):
361 argset['enum_prefix'] = fi.enumPrefix()
362 facet_var = ReferenceFacetMember(type_definition=td, facet_class=fc, **kw)
363 outf.write("%s = %s(%s)\n" % binding_module.literal( (facet_var, fc, argset ), **kw))
364 facet_instances.append(binding_module.literal(facet_var, **kw))
365 if (fi is not None) and is_collection:
366 for i in fi.items():
367 if isinstance(i, facets._EnumerationElement):
368 enum_config = '%s.addEnumeration(unicode_value=%s, tag=%s)' % binding_module.literal( ( facet_var, i.unicodeValue(), i.tag() ), **kw)
369 if gen_enum_tag and (i.tag() is not None):
370 enum_member = ReferenceEnumerationMember(type_definition=td, facet_instance=fi, enumeration_element=i, **kw)
371 outf.write("%s = %s\n" % (binding_module.literal(enum_member, **kw), enum_config))
372 if fi.enumPrefix() is not None:
373 outf.write("%s_%s = %s\n" % (fi.enumPrefix(), i.tag(), binding_module.literal(enum_member, **kw)))
374 else:
375 outf.write("%s\n" % (enum_config,))
376 if isinstance(i, facets._PatternElement):
377 outf.write("%s.addPattern(pattern=%s)\n" % binding_module.literal( (facet_var, i.pattern ), **kw))
378 if gen_enum_tag and (xs.structures.SimpleTypeDefinition.VARIETY_union == td.variety()):
379
380
381
382 fi = td.facets().get(facets.CF_enumeration)
383 if fi is None:
384
385 for mtd in td.memberTypeDefinitions():
386 if not _useEnumerationTags(mtd):
387 continue
388 fi = mtd.facets().get(facets.CF_enumeration)
389 if fi is None:
390 continue
391 for i in fi.items():
392 assert isinstance(i, facets._EnumerationElement)
393 etd = i.enumeration().ownerTypeDefinition()
394 enum_member = ReferenceEnumerationMember(type_definition=td, facet_instance=fi, enumeration_element=i, **kw)
395 outf.write("%-50s%s\n" % ('%s = %s' % binding_module.literal( (enum_member, i.unicodeValue()) ),
396 '# originally %s.%s' % (binding_module.literal(etd), i.tag())))
397 if 2 <= len(facet_instances):
398 map_args = ",\n ".join(facet_instances)
399 else:
400 map_args = ','.join(facet_instances)
401 outf.write("%s._InitializeFacetMap(%s)\n" % (binding_module.literal(td, **kw), map_args))
402
404
405 binding_module = generator.moduleForComponent(std)
406 outf = binding_module.bindingIO()
407
408 class_keywords = frozenset(basis.simpleTypeDefinition._ReservedSymbols)
409 class_unique = set()
410
411 kw = { }
412 kw['binding_module'] = binding_module
413 kw['class_keywords'] = class_keywords
414 kw['class_unique'] = class_unique
415
416 parent_classes = [ binding_module.literal(std.baseTypeDefinition(), **kw) ]
417 enum_facet = std.facets().get(facets.CF_enumeration, None)
418 if (enum_facet is not None) and (enum_facet.ownerTypeDefinition() == std):
419 parent_classes.append('pyxb.binding.basis.enumeration_mixin')
420
421 template_map = { }
422 binding_name = template_map['std'] = binding_module.literal(std, **kw)
423 if (std.expandedName() is not None) and (std.expandedName().localName() != binding_name):
424 _log.warning('Simple type %s renamed to %s', std.expandedName(), binding_name)
425
426 template_map['superclasses'] = ''
427 if 0 < len(parent_classes):
428 template_map['superclasses'] = ', '.join(parent_classes)
429 template_map['expanded_name'] = binding_module.literal(std.expandedName(), **kw)
430 if std.expandedName() is not None:
431 template_map['qname'] = unicode(std.expandedName())
432 else:
433 template_map['qname'] = '[anonymous]'
434 template_map['namespaceReference'] = binding_module.literal(std.bindingNamespace(), **kw)
435 template_map['defn_location'] = repr(std._location())
436 if std.annotation() is not None:
437 template_map['documentation'] = std.annotation().asDocString()
438 template_map['documentation_expr'] = binding_module.literal(std.annotation().text())
439 else:
440 template_map['documentation'] = ''
441 template_map['documentation_expr'] = binding_module.literal(None)
442
443
444
445 common_template = '''
446 """%{documentation}"""
447
448 _ExpandedName = %{expanded_name}
449 _DefinitionLocation = %{defn_location}
450 _Documentation = %{documentation_expr}
451 '''
452 if xs.structures.SimpleTypeDefinition.VARIETY_absent == std.variety():
453 template = '''
454 # The ur simple type: %{qname}
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 simple type: %{qname}
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 simple type: %{qname}
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 simple type: %{qname}
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['qname'] = unicode(ed.expandedName())
508 template_map['decl_location'] = repr(ed._location())
509 template_map['namespaceReference'] = binding_module.literal(ed.bindingNamespace(), **kw)
510 if (ed.SCOPE_global == ed.scope()):
511 binding_name = template_map['class'] = binding_module.literal(ed, **kw)
512 if ed.expandedName().localName() != binding_name:
513 _log.warning('Element %s renamed to %s', ed.expandedName(), binding_name)
514 template_map['localName'] = binding_module.literal(ed.name(), **kw)
515 template_map['map_update'] = templates.replaceInText("%{namespaceReference}.addCategoryObject('elementBinding', %{localName}, %{class})", **template_map)
516 else:
517 template_map['scope'] = binding_module.literal(ed.scope(), **kw)
518 if ed.annotation() is not None:
519 template_map['documentation'] = binding_module.literal(unicode(ed.annotation()))
520 if ed.abstract():
521 template_map['abstract'] = binding_module.literal(ed.abstract(), **kw)
522 if ed.nillable():
523 template_map['nillable'] = binding_module.literal(ed.nillable(), **kw)
524 if ed.default():
525 template_map['defaultValue'] = binding_module.literal(ed.default(), **kw)
526 template_map['typeDefinition'] = binding_module.literal(ed.typeDefinition(), **kw)
527 if ed.substitutionGroupAffiliation():
528 template_map['substitution_group'] = binding_module.literal(ed.substitutionGroupAffiliation(), **kw)
529 aux_init = []
530 for k in ( 'nillable', 'abstract', 'scope', 'documentation' ):
531 if k in template_map:
532 aux_init.append('%s=%s' % (k, template_map[k]))
533 template_map['element_aux_init'] = ''
534 if 0 < len(aux_init):
535 template_map['element_aux_init'] = ', ' + ', '.join(aux_init)
536
537 return template_map
538
540 binding_module = generator.moduleForComponent(ctd)
541 outf = binding_module.bindingIO()
542
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 _log.warning('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 if ctd.expandedName() is not None:
556 template_map['qname'] = unicode(ctd.expandedName())
557 else:
558 template_map['qname'] = '[anonymous]'
559 template_map['defn_location'] = repr(ctd._location())
560 template_map['simple_base_type'] = binding_module.literal(None, **kw)
561 template_map['contentTypeTag'] = content_type_tag
562 template_map['is_abstract'] = repr(not not ctd.abstract())
563
564 content_basis = None
565 if (ctd.CT_SIMPLE == content_type_tag):
566 content_basis = ctd.contentType()[1]
567 template_map['simple_base_type'] = binding_module.literal(content_basis, **kw)
568 elif (ctd.CT_MIXED == content_type_tag):
569 content_basis = ctd.contentType()[1]
570 elif (ctd.CT_ELEMENT_ONLY == content_type_tag):
571 content_basis = ctd.contentType()[1]
572
573 prolog_template = '''
574 # Complex type %{qname} with content type %{contentTypeTag}
575 class %{ctd} (%{superclass}):
576 _TypeDefinition = %{simple_base_type}
577 _ContentTypeTag = pyxb.binding.basis.complexTypeDefinition._CT_%{contentTypeTag}
578 _Abstract = %{is_abstract}
579 _ExpandedName = %{expanded_name}
580 _DefinitionLocation = %{defn_location}
581 '''
582
583
584
585
586 inherits_from_base = True
587 template_map['superclass'] = binding_module.literal(base_type, **kw)
588 if ctd._isHierarchyRoot():
589 inherits_from_base = False
590 template_map['superclass'] = 'pyxb.binding.basis.complexTypeDefinition'
591 assert base_type.nameInBinding() is not None
592
593
594 class_keywords = frozenset(basis.complexTypeDefinition._ReservedSymbols)
595 class_unique = set()
596
597
598
599
600
601
602
603 element_uses = []
604
605 definitions = []
606
607 definitions.append('# Base type is %{base_type}')
608
609
610
611
612
613 if isinstance(content_basis, xs.structures.Particle):
614 plurality_data = content_basis.pluralityData().combinedPlurality()
615
616 outf.postscript().append("\n\n")
617 for (ed, is_plural) in plurality_data.items():
618
619 ef_map = ed._templateMap()
620 ef_map['use_location'] = repr(content_basis._location())
621 if ed.scope() == ctd:
622 ef_map.update(elementDeclarationMap(ed, binding_module, **kw))
623 aux_init = []
624 ef_map['is_plural'] = repr(is_plural)
625 element_uses.append(templates.replaceInText('%{use}.name() : %{use}', **ef_map))
626 if 0 == len(aux_init):
627 ef_map['aux_init'] = ''
628 else:
629 ef_map['aux_init'] = ', ' + ', '.join(aux_init)
630 ef_map['element_binding'] = utility.PrepareIdentifier('%s_elt' % (ef_map['id'],), class_unique, class_keywords, private=True)
631 if ed.annotation() is not None:
632 ef_map['documentation'] = binding_module.literal(unicode(ed.annotation()))
633 else:
634 ef_map['documentation'] = binding_module.literal(None)
635 if ed.scope() != ctd:
636 definitions.append(templates.replaceInText('''
637 # Element %{id} (%{qname}) inherited from %{decl_type_en}''', decl_type_en=unicode(ed.scope().expandedName()), **ef_map))
638 continue
639
640 if ed.expandedName().localName() != ef_map['id']:
641 _log.warning('Element use %s.%s renamed to %s', ctd.expandedName(), ed.expandedName(), ef_map['id'])
642 definitions.append(templates.replaceInText('''
643 # Element %{qname} uses Python identifier %{id}
644 %{use} = pyxb.binding.content.ElementUse(%{name_expr}, '%{id}', '%{key}', %{is_plural}%{aux_init})
645 %{use}._DeclarationLocation = %{decl_location}
646 %{use}._UseLocation = %{use_location}
647 ''', name_expr=binding_module.literal(ed.expandedName(), **kw), **ef_map))
648
649 definitions.append(templates.replaceInText('''
650 %{inspector} = property(%{use}.value, %{use}.set, None, %{documentation})
651 ''', **ef_map))
652 outf.postscript().append(templates.replaceInText('''
653 %{ctd}._AddElement(pyxb.binding.basis.element(%{name_expr}, %{typeDefinition}%{element_aux_init}))
654 ''', name_expr=binding_module.literal(ed.expandedName(), **kw), ctd=template_map['ctd'], **ef_map))
655
656 (particle_val, lines) = GenerateContentParticle(ctd=ctd, particle=content_basis, binding_module=binding_module, **kw)
657 if lines:
658 outf.postscript().append("\n".join(lines))
659 outf.postscript().append("\n")
660 outf.postscript().append(templates.replaceInText('%{ctd}._ContentModel = %{particle_val}', ctd=template_map['ctd'], particle_val=particle_val))
661 outf.postscript().append("\n")
662
663
664 attribute_uses = []
665
666
667
668
669
670
671
672
673 for au in ctd.attributeUses():
674 ad = au.attributeDeclaration()
675 assert isinstance(ad.scope(), xs.structures.ComplexTypeDefinition), 'unexpected scope %s' % (ad.scope(),)
676 au_map = ad._templateMap()
677 if ad.scope() != ctd:
678 definitions.append(templates.replaceInText('''
679 # Attribute %{id} inherited from %{decl_type_en}''', decl_type_en=unicode(ad.scope().expandedName()), **au_map))
680 continue
681 assert isinstance(au_map, dict)
682 aur = au;
683 while aur.restrictionOf() is not None:
684 aur = aur.restrictionOf()
685 if au != aur:
686 au_map = aur.attributeDeclaration()._templateMap().copy()
687 definitions.append(templates.replaceInText('''
688 # Attribute %{id} is restricted from parent''', **au_map))
689
690 assert ad.typeDefinition() is not None
691 au_map['attr_type'] = binding_module.literal(ad.typeDefinition(), **kw)
692 au_map['decl_location'] = repr(ad._location())
693 au_map['use_location'] = repr(au._location())
694
695 vc_source = ad
696 if au.valueConstraint() is not None:
697 vc_source = au
698 aux_init = []
699 if vc_source.fixed() is not None:
700 aux_init.append('fixed=True')
701 aux_init.append('unicode_default=%s' % (binding_module.literal(vc_source.fixed(), **kw),))
702 elif vc_source.default() is not None:
703 aux_init.append('unicode_default=%s' % (binding_module.literal(vc_source.default(), **kw),))
704 if au.required():
705 aux_init.append('required=True')
706 if au.prohibited():
707 aux_init.append('prohibited=True')
708 if 0 == len(aux_init):
709 au_map['aux_init'] = ''
710 else:
711 aux_init.insert(0, '')
712 au_map['aux_init'] = ', '.join(aux_init)
713 if ad.annotation() is not None:
714 au_map['documentation'] = binding_module.literal(unicode(ad.annotation()))
715 else:
716 au_map['documentation'] = binding_module.literal(None)
717
718 attribute_uses.append(templates.replaceInText('%{use}.name() : %{use}', **au_map))
719 if ad.expandedName().localName() != au_map['id']:
720 _log.warning('Attribute %s.%s renamed to %s', ctd.expandedName(), ad.expandedName(), au_map['id'])
721 definitions.append(templates.replaceInText('''
722 # Attribute %{qname} uses Python identifier %{id}
723 %{use} = pyxb.binding.content.AttributeUse(%{name_expr}, '%{id}', '%{key}', %{attr_type}%{aux_init})
724 %{use}._DeclarationLocation = %{decl_location}
725 %{use}._UseLocation = %{use_location}''', name_expr=binding_module.literal(ad.expandedName(), **kw), **au_map))
726 if au.prohibited():
727 definitions.append(templates.replaceInText('''
728 %{inspector} = property()
729 ''', ctd=template_map['ctd'], **au_map))
730 else:
731 definitions.append(templates.replaceInText('''
732 %{inspector} = property(%{use}.value, %{use}.set, None, %{documentation})
733 ''', ctd=template_map['ctd'], **au_map))
734
735 if ctd.attributeWildcard() is not None:
736 definitions.append('_AttributeWildcard = %s' % (binding_module.literal(ctd.attributeWildcard(), **kw),))
737 if ctd.hasWildcardElement():
738 definitions.append('_HasWildcardElement = True')
739 template_map['attribute_uses'] = ",\n ".join(attribute_uses)
740 template_map['element_uses'] = ",\n ".join(element_uses)
741 if inherits_from_base:
742 map_decl = '''
743 _ElementMap = %{superclass}._ElementMap.copy()
744 _ElementMap.update({
745 %{element_uses}
746 })
747 _AttributeMap = %{superclass}._AttributeMap.copy()
748 _AttributeMap.update({
749 %{attribute_uses}
750 })'''
751 else:
752 map_decl = '''
753 _ElementMap = {
754 %{element_uses}
755 }
756 _AttributeMap = {
757 %{attribute_uses}
758 }'''
759
760 template_map['registration'] = ''
761 if ctd.name() is not None:
762 template_map['registration'] = templates.replaceInText("%{namespaceReference}.addCategoryObject('typeBinding', %{localName}, %{ctd})",
763 localName=binding_module.literal(ctd.name(), **kw), **template_map)
764
765 template = ''.join([prolog_template,
766 " ", "\n ".join(definitions), "\n",
767 map_decl, '''
768 %{registration}
769
770 '''])
771
772 outf.write(template, **template_map)
773
775
776 assert ed._scopeIsGlobal()
777
778 binding_module = generator.moduleForComponent(ed)
779 outf = binding_module.bindingIO()
780
781 template_map = elementDeclarationMap(ed, binding_module, **kw)
782 template_map.setdefault('scope', binding_module.literal(None, **kw))
783 template_map.setdefault('map_update', '')
784
785 outf.write(templates.replaceInText('''
786 %{class} = pyxb.binding.basis.element(%{name_expr}, %{typeDefinition}%{element_aux_init})
787 %{namespaceReference}.addCategoryObject('elementBinding', %{class}.name().localName(), %{class})
788 ''', name_expr=binding_module.literal(ed.expandedName(), **kw), **template_map))
789
790 if ed.substitutionGroupAffiliation() is not None:
791 outf.postscript().append(templates.replaceInText('''
792 %{class}._setSubstitutionGroup(%{substitution_group})
793 ''', **template_map))
794
803
822
824 use_map = component._templateMap()
825 class_unique = nsm.uniqueInClass(container)
826 assert isinstance(component, xs.structures._ScopedDeclaration_mixin)
827 unique_name = utility.PrepareIdentifier(component.expandedName().localName(), class_unique)
828 use_map['id'] = unique_name
829 use_map['inspector'] = unique_name
830 use_map['mutator'] = utility.PrepareIdentifier('set' + unique_name[0].upper() + unique_name[1:], class_unique)
831 use_map['use'] = utility.MakeUnique('__' + unique_name.strip('_'), class_unique)
832 assert component._scope() == container
833 assert component.nameInBinding() is None, 'Use %s but binding name %s for %s' % (use_map['use'], component.nameInBinding(), component.expandedName())
834 component.setNameInBinding(use_map['use'])
835 key_name = '%s_%s_%s' % (str(nsm.namespace()), container.nameInBinding(), component.expandedName())
836 use_map['key'] = utility.PrepareIdentifier(key_name, class_unique, private=True)
837 use_map['qname'] = unicode(component.expandedName())
838 if isinstance(component, xs.structures.ElementDeclaration) and is_plural:
839 use_map['appender'] = utility.PrepareIdentifier('add' + unique_name[0].upper() + unique_name[1:], class_unique)
840 return use_map
841
903
905 __anonSTDIndex = None
906 __anonCTDIndex = None
907 __uniqueInModule = None
908 __uniqueInClass = None
909
910
911 _UniqueInModule = set([ 'pyxb', 'sys' ])
912
913 __ComponentBindingModuleMap = {}
914
917 __generator = None
918
919 - def __init__ (self, generator, *args, **kw):
933
941
959
960 __referencedNamespaces = None
961
963 return self.__bindingIO
964
965 __moduleUID = None
970
973
975 """Return a distinct string recorded in the first 4096 bytes of the binding file.
976
977 This is used to ensure uniqueness and avoid overwriting data
978 belonging to a different binding. The return value comprises
979 the class-specialized L{_bindingTagPrefix_vx} with the
980 L{moduleUID}.
981 """
982 return '%s:%s' % (self._bindingTagPrefix_vx(), self.moduleUID())
983
985 raise pyxb.LogicError('Subclass %s does not define _bindingTagPrefix_vx' % (type(self),))
986
988 """Return a block of binding text (comment or code) serving as a preface.
989
990 Normally this should describe the module contents."""
991 return self._bindingPreface_vx()
994
995 - def moduleContents (self):
996 template_map = {}
997 aux_imports = []
998 for ns in self.__importedModules:
999 if isinstance(ns, NamespaceModule):
1000 ns = ns.moduleRecord()
1001 module_path = ns.modulePath()
1002 assert module_path is not None, 'No module path for %s type %s' % (ns, type(ns))
1003 aux_imports.append('import %s' % (module_path,))
1004 template_map['aux_imports'] = "\n".join(aux_imports)
1005 template_map['namespace_decls'] = "\n".join(self.__namespaceDeclarations)
1006 template_map['module_uid'] = self.moduleUID()
1007 template_map['generation_uid_expr'] = repr(self.generator().generationUID())
1008 self._finalizeModuleContents_vx(template_map)
1009 return self.__bindingIO.contents()
1010
1023 __modulePath = None
1024
1027 __bindingFile = None
1028 __bindingFilePath = None
1029
1032
1035
1036 @classmethod
1040
1041 @classmethod
1044
1045 @classmethod
1049 @classmethod
1052 __RecordModuleMap = { }
1053
1071 return self.__componentNameMap.get(component)
1072
1091
1093
1094 - def defineNamespace (self, namespace, name, require_unique=True, definition=None, **kw):
1108
1110 rv = self.__referencedNamespaces.get(namespace)
1111 if rv is None:
1112 if namespace.isBuiltinNamespace():
1113 rv = namespace.builtinNamespaceRepresentation()
1114 elif namespace.isUndeclaredNamespace():
1115 rv = namespace.modulePath()
1116 elif isinstance(self, NamespaceModule):
1117 if (self.namespace() == namespace):
1118 rv = 'Namespace'
1119 else:
1120 rv = 'pyxb.namespace.NamespaceForURI(%s)' % (repr(namespace.uri()),)
1121 '''
1122 namespace_module = self.ForNamespace(namespace)
1123 if namespace_module is not None:
1124 self._importModule(namespace_module)
1125 rv = '%s.Namespace' % (namespace_module.modulePath(),)
1126 else:
1127 assert False, 'Unexpected reference to %s' % (namespace,)
1128 #rv = 'pyxb.namespace.NamespaceForURI(%s)' % (repr(namespace.uri()),)
1129 '''
1130 else:
1131 if namespace.prefix():
1132 nsn = 'Namespace_%s' % (namespace.prefix(),)
1133 else:
1134 nsn = 'Namespace'
1135 for im in self.__importedModules:
1136 if isinstance(im, NamespaceModule) and (im.namespace() == namespace):
1137 rv = '%s.Namespace' % (im.modulePath(),)
1138 break
1139 if isinstance(im, NamespaceGroupModule):
1140 irv = im.__referencedNamespaces.get(namespace)
1141 if irv is not None:
1142 rv = self.defineNamespace(namespace, nsn, '%s.%s' % (im.modulePath(), irv), protected=True)
1143 break
1144 if rv is None:
1145 rv = self.defineNamespace(namespace, nsn, protected=True)
1146 assert 0 < len(self.__namespaceDeclarations)
1147 self.__referencedNamespaces[namespace] = rv
1148 return rv
1149
1151 return self.__bindingIO.literal(*args, **kw)
1152
1166
1174
1177 """This class represents a Python module that holds all the
1178 declarations belonging to a specific namespace."""
1179
1182 __namespace = None
1183
1186 __moduleRecord = None
1187
1192 __namespaceGroupModule = None
1193
1194 _UniqueInModule = _ModuleNaming_mixin._UniqueInModule.copy()
1195 _UniqueInModule.update([ 'Namespace', 'CreateFromDOM', 'CreateFromDocument' ])
1196
1199 __namespaceGroupHead = None
1200 __namespaceGroup = None
1201
1204 __components = None
1205
1206 @classmethod
1209 __ComponentModuleMap = { }
1210
1213
1215 ns = self.namespace()
1216 rvl = ['# Namespace %s' % (ns,)]
1217 if ns.prefix() is not None:
1218 rvl.append(' [xmlns:%s]' % (ns.prefix(),))
1219 rvl.append('\n')
1220 return ''.join(rvl)
1221
1226
1229
1230 - def __init__ (self, generator, module_record, mr_scc, components=None, **kw):
1244
1252
1253 - def _finalizeModuleContents_vx (self, template_map):
1254 self.bindingIO().prolog().append(self.bindingIO().expand('''
1255 import pyxb
1256 import pyxb.binding
1257 import pyxb.binding.saxer
1258 import StringIO
1259 import pyxb.utils.utility
1260 import pyxb.utils.domutils
1261 import sys
1262
1263 # Unique identifier for bindings created at the same time
1264 _GenerationUID = %{generation_uid_expr}
1265
1266 # Import bindings for namespaces imported into schema
1267 %{aux_imports}
1268
1269 %{namespace_decls}
1270 ModuleRecord = Namespace.lookupModuleRecordByUID(_GenerationUID, create_if_missing=True)
1271 ModuleRecord._setModule(sys.modules[__name__])
1272
1273 def CreateFromDocument (xml_text, default_namespace=None, location_base=None):
1274 """Parse the given XML and use the document element to create a
1275 Python instance.
1276
1277 @kw default_namespace The L{pyxb.Namespace} instance to use as the
1278 default namespace where there is no default namespace in scope.
1279 If unspecified or C{None}, the namespace of the module containing
1280 this function will be used.
1281
1282 @keyword location_base: An object to be recorded as the base of all
1283 L{pyxb.utils.utility.Location} instances associated with events and
1284 objects handled by the parser. You might pass the URI from which
1285 the document was obtained.
1286 """
1287
1288 if pyxb.XMLStyle_saxer != pyxb._XMLStyle:
1289 dom = pyxb.utils.domutils.StringToDOM(xml_text)
1290 return CreateFromDOM(dom.documentElement)
1291 if default_namespace is None:
1292 default_namespace = Namespace.fallbackNamespace()
1293 saxer = pyxb.binding.saxer.make_parser(fallback_namespace=default_namespace, location_base=location_base)
1294 handler = saxer.getContentHandler()
1295 saxer.parse(StringIO.StringIO(xml_text))
1296 instance = handler.rootObject()
1297 return instance
1298
1299 def CreateFromDOM (node, default_namespace=None):
1300 """Create a Python instance from the given DOM node.
1301 The node tag must correspond to an element declaration in this module.
1302
1303 @deprecated: Forcing use of DOM interface is unnecessary; use L{CreateFromDocument}."""
1304 if default_namespace is None:
1305 default_namespace = Namespace.fallbackNamespace()
1306 return pyxb.binding.basis.element.AnyCreateFromDOM(node, _fallback_namespace=default_namespace)
1307
1308 ''', **template_map))
1309
1310 __components = None
1311 __componentBindingName = None
1312
1321
1324
1394
1395
1396 -def GeneratePython (schema_location=None,
1397 schema_text=None,
1398 namespace=None,
1399 module_prefix_elts=[],
1400 **kw):
1411
1412 import optparse
1413 import re
1416 """Configuration and data for a single binding-generation action."""
1417
1418 _DEFAULT_bindingRoot = '.'
1420 """The directory path into which generated bindings will be written.
1421 @rtype: C{str}"""
1422 return self.__bindingRoot
1426 __bindingRoot = None
1427
1429 if isinstance(module_elts, basestring):
1430 module_elts = module_elts.split('.')
1431 else:
1432 module_elts = module_elts[:]
1433 assert 0 < len(module_elts)
1434 if not inhibit_extension:
1435 assert not module_elts[-1].endswith('.py')
1436 module_elts[-1] = '%s.py' % (module_elts[-1],)
1437 return os.path.join(self.bindingRoot(), *module_elts)
1438
1441 __generateToFiles = None
1442
1444
1445
1446
1447
1448 module_path = None
1449 if isinstance(module, NamespaceModule):
1450 mr = module.moduleRecord()
1451 if mr is None:
1452 return ('/dev/null', None, None)
1453 if self.generationUID() != mr.generationUID():
1454 return ('/dev/null', None, None)
1455 if not self.generateToFiles():
1456 return ('/dev/null', None, None)
1457 if mr.namespace().isBuiltinNamespace() and (not self.allowBuiltinGeneration()):
1458 return ('/dev/null', None, None)
1459 module_path = mr.modulePath()
1460 assert module_path is not None, 'No path specified for module %s' % (mr,)
1461
1462
1463
1464 module_elts = module_path.split('.')
1465 if self.writeForCustomization():
1466 import_file_path = self.__moduleFilePath(module_elts)
1467 module_elts.insert(-1, 'raw')
1468 if not os.path.exists(import_file_path):
1469 raw_module_path = '.'.join(module_elts)
1470 pyxb.utils.utility.OpenOrCreate(import_file_path).write("from %s import *\n" % (raw_module_path,))
1471 binding_file_path = self.__moduleFilePath(module_elts)
1472 try:
1473 binding_file = pyxb.utils.utility.OpenOrCreate(binding_file_path, tag=module.moduleUID())
1474 except OSError, e:
1475 if errno.EEXIST == e.errno:
1476 raise pyxb.BindingGenerationError('Target file %s for module %s bindings exists with other content' % (binding_file_path, mr))
1477 raise
1478 elif isinstance(module, NamespaceGroupModule):
1479 if not self.generateToFiles():
1480 raise pyxb.BindingGenerationError('Generation of namespace groups requires generate-to-files')
1481 module_elts = []
1482 if self.modulePrefix():
1483 module_elts.extend(self.modulePrefix().split('.'))
1484 if self.writeForCustomization():
1485 module_elts.append('raw')
1486 in_use = set()
1487 while True:
1488 module_elts.append(pyxb.utils.utility.PrepareIdentifier('nsgroup', in_use, protected=True))
1489 try:
1490 binding_file_path = self.__moduleFilePath(module_elts)
1491 _log.info('Attempting group %s uid %s at %s', module, module.moduleUID(), binding_file_path)
1492 binding_file = pyxb.utils.utility.OpenOrCreate(binding_file_path, tag=module.moduleUID())
1493 break
1494 except OSError, e:
1495 if errno.EEXIST != e.errno:
1496 raise
1497 module_elts.pop()
1498 module_path = '.'.join(module_elts)
1499 else:
1500 assert False
1501 if self.generateToFiles():
1502 for n in range(len(module_elts)-1):
1503 sub_path = self.__moduleFilePath(module_elts[:1+n], inhibit_extension=True)
1504 init_path = os.path.join(sub_path, '__init__.py')
1505 if not os.path.exists(init_path):
1506 file(init_path, 'w')
1507 return (binding_file_path, binding_file, module_path)
1508
1510 """The directory from which entrypoint schemas specified as
1511 relative file paths will be read."""
1512 return self.__schemaRoot
1514 if not schema_root.endswith(os.sep):
1515 schema_root = schema_root + os.sep
1516 self.__schemaRoot = schema_root
1517 return self
1518 __schemaRoot = None
1519
1521 """Optional string that is stripped from the beginning of
1522 schemaLocation values before loading from them.
1523
1524 This applies only to the values of schemaLocation attributes
1525 in C{import} and C{include} elements. Its purpose is to
1526 convert absolute schema locations into relative ones to allow
1527 offline processing when all schema are available in a local
1528 directory. See C{schemaRoot}.
1529 """
1530 return self.__schemaStrippedPrefix
1534 __schemaStrippedPrefix = None
1535
1537 """Optional map to rewrite schema locations.
1538
1539 This applies only to the values of schemaLocation attributes
1540 in C{import} and C{include} elements. Its purpose is to
1541 convert remote or absolute schema locations into local or
1542 relative ones to allow offline processing when all schema are
1543 available in a local directory. See C{schemaRoot}.
1544 """
1545 return self.__locationPrefixRewriteMap
1551 """Add a rewrite entry for schema locations.
1552
1553 @param prefix : A text prefix that should be removed from
1554 schema location URIs.
1555
1556 @param substituent : The text prefix that should replace
1557 C{prefix} as a prefix in a schema location URI.
1558 """
1559
1560 self.__locationPrefixRewriteMap[prefix] = substituent
1561 return self
1563 """Add a rewrite entry for schema locations.
1564
1565 Parameter values are strings of the form C{pfx=sub}. The
1566 effect is that a schema location that begins with C{pfx} is
1567 rewritten so that it instead begins with C{sub}."""
1568 try:
1569 (prefix, substituent) = prefix_rewrite.split('=', 1)
1570 except:
1571 raise
1572 self.addLocationPrefixRewrite(prefix, substituent)
1573 __locationPrefixMap = {}
1574
1576 """A list of locations from which entrypoint schemas are to be
1577 read.
1578
1579 The values in the list are either URIs, or tuples consisting
1580 of a value and a callable which, when passed the generator
1581 object and the value, will return a
1582 L{pyxb.xmlschema.structures.Schema} instance. See
1583 L{addSchemaLocation}.
1584
1585 See also L{addSchemaLocation} and L{schemas}.
1586 """
1587 return self.__schemaLocationList
1593 """Add the location of an entrypoint schema.
1594
1595 @param schema_location: The location of the schema. This
1596 should be a URL; if the schema location does not have a URL
1597 scheme (e.g., C{http:}), it is assumed to be a file, and if it
1598 is not an absolute path is located relative to the
1599 C{schemaRoot}.
1600
1601 @keyword converter: Optional callable that will be invoked
1602 with the generator instance and the schema location, and is
1603 expected to return a L{pyxb.xmlschema.structures.Schema}
1604 instance. If absent, the contents of the location are
1605 converted directly.
1606
1607 @note: The C{converter} argument derives from WSDL support: we
1608 need to add to the sequence of schema locations a URI of
1609 something that will not parse as a schema, but does have inner
1610 material that can if treated properly. "Treated properly" may
1611 include having the archive path and other namespace
1612 manipulations configured before anything is done to it.
1613 """
1614 self.__schemaLocationList.append( (schema_location, converter) )
1615 return self
1617 """Add the location of an entrypoint schema. The provided
1618 value should be a URL; if it does not have a URL scheme (e.g.,
1619 C{http:}), it is assumed to be a file, and if it is not an
1620 absolute path is located relative to the C{schemaRoot}."""
1621 self.addSchemaLocation(schema_location)
1622 __schemaLocationList = None
1623
1625 """Schema for which bindings should be generated.
1626
1627 These may be L{Schema<pyxb.xmlschema.structures.Schema>}
1628 instances, or strings; the latter is preferred, and is parsed
1629 into a Schema instance when required.
1630
1631 This is the list of entrypoint schemas for binding generation.
1632 Values in L{schemaLocationList} are read and converted into
1633 schema, then appended to this list. Values from L{moduleList}
1634 are applied starting with the first schema in this list.
1635 """
1636 return self.__schemas[:]
1644 __schemas = None
1645
1647 """The set of L{namespaces<pyxb.namespace.Namespace>} for
1648 which bindings will be generated.
1649
1650 This is the set of namespaces read from entrypoint schema,
1651 closed under reference to namespaces defined by schema import.
1652
1653 @rtype: C{set}
1654 """
1655 return self.__namespaces.copy()
1663 __namespaces = None
1664
1666 """A list of module names to be applied in order to the namespaces of entrypoint schemas"""
1667 return self.__moduleList[:]
1672
1674 """Add a module name corresponding to an entrypoint schema.
1675
1676 The namespace defined by the corresponding schema will be
1677 written to a binding using the given module name, adjusted by
1678 L{modulePrefix}."""
1679 self.__moduleList.append(module_name)
1680 return self
1681 __moduleList = None
1682
1684 """The prefix for binding modules.
1685
1686 The base name for the module holding a binding is taken from
1687 the moduleList, moduleMap, or an XMLNS prefix associated with
1688 the namespace in a containing schema. This value, if present,
1689 is used as a prefix to allow a deeper module hierarchy."""
1690 return self.__modulePrefix
1694 __modulePrefix = None
1695
1697 """A map from namespace URIs to the module to be used for the
1698 corresponding generated binding.
1699
1700 Module values are adjusted by L{modulePrefix} if that has been
1701 specified.
1702
1703 An entry in this map for a namespace supersedes the module
1704 specified in moduleList if the namespace is defined by an
1705 entrypoint schema.
1706
1707 @return: A reference to the namespace module map.
1708 """
1709 return self.__namespaceModuleMap
1710 __namespaceModuleMap = None
1711
1713 """A colon-separated list of paths from which namespace
1714 archives can be read.
1715
1716 The default path is the contents of the C{PYXB_ARCHIVE_PATH}
1717 environment variable, or the standard path configured at
1718 installation time. Any file with the extension C{.wxs} found
1719 in one of these directories is examined to see whether it is a
1720 namespace archive.
1721 """
1722 return self.__archivePath
1726 __archivePath = None
1727
1729 """A frozenset of namespaces that many not be loaded from an archive."""
1730 return frozenset(self.__noLoadNamespaces)
1732 """Record the set of namespaces that should not be loaded from an archive.
1733
1734 The expectation is that any required entities in the namespace
1735 will be defined by loading schema."""
1736 self.__noLoadNamespaces.clear()
1737 self.__noLoadNamespaces.update([ pyxb.namespace.NamespaceInstance(_ns) for _ns in namespace_set ])
1739 """Mark that the specified namespace should not be loaded from an archive.
1740
1741 Use this when you are generating bindings for an application
1742 that has a restricted profile of a namespace that would
1743 otherwise be read from an archive. Be aware that this removes
1744 any knowledge of any archive in which this namespace is
1745 present as a non-private member."""
1746 self.__noLoadNamespaces.add(pyxb.namespace.NamespaceInstance(namespace))
1747 __noloadNamespaces = None
1748
1750 """A list of paths to archives that should be loaded, in order, prior to parsing schema."""
1751 return frozenset(self.__preLoadArchives)
1753 """Name of a file containing a stored archive from which
1754 namespaces should be read prior to processing schema.
1755
1756 Files to be pre-loaded are not affected by
1757 C{noLoadNamespace}."""
1758 self.__preLoadArchives.append(archive_file)
1762 __preLoadArchives = None
1763
1765 """Optional file into which the archive of namespaces will be written.
1766
1767 Subsequent generation actions can read pre-parsed namespaces
1768 from this file, and therefore reference the bindings that were
1769 built earlier rather than re-generating them.
1770
1771 The file name should normally end with C{.wxs}."""
1772 return self.__archiveToFile
1776 __archiveToFile = None
1777
1791 """Indicates, for specific namespaces, whether their
1792 visibility in the archive should be public or private."""
1793 return self.__namespaceVisibilityMap.copy()
1794 __namespaceVisibilityMap = None
1795
1797 """Indicates whether unmentioned namespaces will be public or private (default) in the archive.
1798
1799 A namespace is I{mentioned} if it is the target namespace of
1800 an entrypoint schema, or appears in a namespace visibility
1801 specification. I.e., this default applies only to namespaces
1802 that are modified as a result of including some schema, which
1803 is generally a local customization of something.
1804 """
1805 return self.__defaultNamespacePublic
1808 __defaultNamespacePublic = None
1809
1811 """Indicates whether the bindings should validate mutations
1812 against the content model."""
1813 return self.__validateChanges
1818 __validateChanges = None
1819
1821 """Indicates whether the binding Python code should be written into a sub-module for customization.
1822
1823 If enabled, a module C{path.to.namespace} will be written to
1824 the file C{path/to/raw/namespace.py}, so that the file
1825 C{path/to/namespace.py} can import it and override behavior."""
1826 return self.__writeForCustomization
1830 __writeForCustomization = None
1831
1833 """Indicates whether the code generator is permitted to
1834 process namespace for which no module path can be determined.
1835
1836 Use this only when generating bindings that will not be
1837 referenced by other bindings."""
1838 return self.__allowAbsentModule
1842 __allowAbsentModule = None
1843
1845 """Indicates whether bindings will be written for namespaces that are built-in to PyXB.
1846
1847 This must be enabled when building bindings for the XML,
1848 XMLSchema instance, and other built-in namespaces. Normally
1849 generation of these namespaces is inhibited lest it produce
1850 inconsistencies."""
1851 return self.__allowBuiltinGeneration
1855 __allowBuiltinGeneration = None
1856
1858 """The directory path into which any content retrieved by URI will be written.
1859
1860 This serves as a local cache, and to give you an opportunity
1861 to inspect material retrieved from some other system.
1862 @rtype: C{str}"""
1863 return self.__uriContentArchiveDirectory
1866 __uriContentArchiveDirectory = None
1867
1869 """A file provided to L{logging.config.fileConfig} to control log messages.
1870
1871 In the absence of other configuration the Python standard logging infrastructure is used in its
1872 default configuration.
1873
1874 @rtype: C{str}"""
1875 return self.__loggingConfigFile
1878 __loggingConfigFile = None
1879
1881 """Create a configuration to be used for generating bindings.
1882
1883 Arguments are treated as additions to the schema location list
1884 after all keywords have been processed.
1885
1886 @keyword binding_root: Invokes L{setBindingRoot}
1887 @keyword schema_root: Invokes L{setSchemaRoot}
1888 @keyword schema_stripped_prefix: Invokes L{setSchemaStrippedPrefix}
1889 @keyword location_prefix_rewrite_map: Invokes L{setLocationPrefixRewriteMap}
1890 @keyword schema_location_list: Invokes L{setSchemaLocationList}
1891 @keyword module_list: Invokes L{_setModuleList}
1892 @keyword module_prefix: Invokes L{setModulePrefix}
1893 @keyword archive_path: Invokes L{setArchivePath}
1894 @keyword no_load_namespaces: Invokes L{_setNoLoadNamespaces}
1895 @keyword pre_load_archives: Invokes L{_setPreLoadArchives}
1896 @keyword archive_to_file: Invokes L{setArchiveToFile}
1897 @keyword public_namespace: Invokes L{setNamespaceVisibility}
1898 @keyword private_namespace: Invokes L{setNamespaceVisibility}
1899 @keyword default_namespace_public: Invokes L{setDefaultNamespacePublic}
1900 @keyword validate_changes: Invokes L{setValidateChanges}
1901 @keyword namespace_module_map: Initializes L{namespaceModuleMap}
1902 @keyword schemas: Invokes L{setSchemas}
1903 @keyword namespaces: Invokes L{setNamespaces}
1904 @keyword write_for_customization: Invokes L{setWriteForCustomization}
1905 @keyword allow_builtin_generation: Invokes L{setAllowBuiltinGeneration}
1906 @keyword allow_absent_module: Invokes L{setAllowAbsentModule}
1907 @keyword generate_to_files: Sets L{generateToFiles}
1908 @keyword uri_content_archive_directory: Invokes L{setUriContentArchiveDirectory}
1909 @keyword logging_config_file: Invokes L{setLoggingConfigFile}
1910 """
1911 argv = kw.get('argv', None)
1912 if argv is not None:
1913 kw = {}
1914 self.__bindingRoot = kw.get('binding_root', self._DEFAULT_bindingRoot)
1915 self.__schemaRoot = kw.get('schema_root', '.')
1916 self.__schemaStrippedPrefix = kw.get('schema_stripped_prefix')
1917 self.__locationPrefixRewriteMap = kw.get('location_prefix_rewrite_map', {})
1918 self.__schemas = []
1919 self.__schemaLocationList = kw.get('schema_location_list', [])[:]
1920 self.__moduleList = kw.get('module_list', [])[:]
1921 self.__modulePrefix = kw.get('module_prefix')
1922 self.__archivePath = kw.get('archive_path', pyxb.namespace.archive.GetArchivePath())
1923 self.__noLoadNamespaces = kw.get('no_load_namespaces', set()).copy()
1924 self.__preLoadArchives = kw.get('pre_load_archives', [])[:]
1925 self.__archiveToFile = kw.get('archive_to_file')
1926 self.__namespaceVisibilityMap = {}
1927 self._setNamespaceVisibilities(kw.get('public_namespaces', set()), kw.get('private_namespaces', set()))
1928 self.__defaultNamespacePublic = kw.get('default_namespace_public', False)
1929 self.__validateChanges = kw.get('validate_changes', True)
1930 self.__namespaceModuleMap = kw.get('namespace_module_map', {}).copy()
1931 self.__schemas = kw.get('schemas', [])[:]
1932 self.__namespaces = set(kw.get('namespaces', []))
1933 self.__writeForCustomization = kw.get('write_for_customization', False)
1934 self.__allowBuiltinGeneration = kw.get('allow_builtin_generation', False)
1935 self.__allowAbsentModule = kw.get('allow_absent_module', False)
1936 self.__generateToFiles = kw.get('generate_to_files', True)
1937 self.__uriContentArchiveDirectory = kw.get('uri_content_archive_directory')
1938 self.__loggingConfigFile = kw.get('logging_config_file')
1939
1940 if argv is not None:
1941 self.applyOptionValues(*self.optionParser().parse_args(argv))
1942 [ self.addSchemaLocation(_a) for _a in args ]
1943
1944 self.__generationUID = pyxb.utils.utility.UniqueIdentifier()
1945
1946 pyxb.namespace.XML.validateComponentModel()
1947
1948 __stripSpaces_re = re.compile('\s\s\s+')
1951
1952 __OptionSetters = (
1953 ('binding_root', setBindingRoot),
1954 ('schema_root', setSchemaRoot),
1955 ('schema_stripped_prefix', setSchemaStrippedPrefix),
1956 ('location_prefix_rewrite', argAddLocationPrefixRewrite),
1957 ('schema_location', setSchemaLocationList),
1958 ('module', _setModuleList),
1959 ('module_prefix', setModulePrefix),
1960 ('archive_path', setArchivePath),
1961 ('no_load_namespace', _setNoLoadNamespaces),
1962 ('pre_load_archive', _setPreLoadArchives),
1963 ('archive_to_file', setArchiveToFile),
1964 ('default_namespace_public', setDefaultNamespacePublic),
1965 ('validate_changes', setValidateChanges),
1966 ('write_for_customization', setWriteForCustomization),
1967 ('allow_builtin_generation', setAllowBuiltinGeneration),
1968 ('allow_absent_module', setAllowAbsentModule),
1969 ('uri_content_archive_directory', setUriContentArchiveDirectory),
1970 ('logging_config_file', setLoggingConfigFile)
1971 )
1985
1987 if argv is None:
1988 argv = sys.argv[1:]
1989 (options, args) = self.optionParser().parse_args(argv)
1990 self.applyOptionValues(options, args)
1991 return self
1992
1994 """A unique identifier associated with this Generator instance.
1995
1996 This is an instance of L{pyxb.utils.utility.UniqueIdentifier}.
1997 Its associated objects are
1998 L{pyxb.namespace.archive._SchemaOrigin} instances, which
1999 identify schema that contribute to the definition of a
2000 namespace."""
2001 return self.__generationUID
2002 __generationUID = None
2003
2005 """Return an C{optparse.OptionParser} instance tied to this configuration.
2006
2007 @param reset: If C{False} (default), a parser created in a
2008 previous invocation will be returned. If C{True}, any
2009 previous option parser is discarded and a new one created.
2010 @type reset: C{bool}
2011 """
2012 if reset or (self.__optionParser is None):
2013 parser = optparse.OptionParser(usage="%prog [options] [more schema locations...]",
2014 version='%%prog from PyXB %s' % (pyxb.__version__,),
2015 description='Generate bindings from a set of XML schemas')
2016
2017 group = optparse.OptionGroup(parser, 'Identifying Schema', 'Specify and locate schema for which bindings should be generated.')
2018 group.add_option('--schema-location', '-u', metavar="FILE_or_URL",
2019 action='append',
2020 help=self.__stripSpaces(self.argAddSchemaLocation.__doc__))
2021 group.add_option('--schema-root', metavar="DIRECTORY",
2022 help=self.__stripSpaces(self.schemaRoot.__doc__))
2023 group.add_option('--schema-stripped-prefix', metavar="TEXT", type='string',
2024 help=self.__stripSpaces(self.schemaStrippedPrefix.__doc__))
2025 group.add_option('--location-prefix-rewrite', metavar="TEXT", type='string',
2026 help=self.__stripSpaces(self.argAddLocationPrefixRewrite.__doc__))
2027 group.add_option('--uri-content-archive-directory', metavar="DIRECTORY",
2028 help=self.__stripSpaces(self.uriContentArchiveDirectory.__doc__))
2029 parser.add_option_group(group)
2030
2031 group = optparse.OptionGroup(parser, 'Configuring Bindings', 'Specify where generated bindings should be written, and how they will be accessed from Python.')
2032 group.add_option('--module', '-m', metavar="MODULE",
2033 action='append',
2034 help=self.__stripSpaces(self.addModuleName.__doc__))
2035 group.add_option('--module-prefix', metavar="MODULE",
2036 help=self.__stripSpaces(self.modulePrefix.__doc__))
2037 group.add_option('--binding-root', metavar="DIRECTORY",
2038 help=self.__stripSpaces(self.bindingRoot.__doc__))
2039 group.add_option('-r', '--write-for-customization',
2040 action='store_true', dest='write_for_customization',
2041 help=self.__stripSpaces(self.writeForCustomization.__doc__ + ' This option turns on the feature.'))
2042 group.add_option('--no-write-for-customization',
2043 action='store_false', dest='write_for_customization',
2044 help=self.__stripSpaces(self.writeForCustomization.__doc__ + ' This option turns off the feature (I{default}).'))
2045 parser.add_option_group(group)
2046
2047 group = optparse.OptionGroup(parser, 'Reading Namespace Archives', 'Locating and loading (or inhibiting load of) namespace archives.')
2048 group.add_option('--archive-path', metavar="PATH",
2049 help=self.__stripSpaces(self.archivePath.__doc__))
2050 group.add_option('--pre-load-archive', metavar="FILE",
2051 action='append',
2052 help=self.__stripSpaces(self.addPreLoadArchive.__doc__))
2053 group.add_option('--no-load-namespace', metavar="URI",
2054 action='append',
2055 help=self.__stripSpaces(self.addNoLoadNamespace.__doc__))
2056 parser.add_option_group(group)
2057
2058 group = optparse.OptionGroup(parser, 'Writing Namespace Archives', 'Control the location and content of a namespace archive corresponding to a binding generation.')
2059 group.add_option('--archive-to-file', metavar="FILE",
2060 help=self.__stripSpaces(self.archiveToFile.__doc__))
2061 group.add_option('--public-namespace', metavar="URI",
2062 action='append',
2063 help=self.__stripSpaces(self.namespaceVisibilityMap.__doc__ + ' This option adds the namespace as a public archive member.'))
2064 group.add_option('--private-namespace', metavar="URI",
2065 action='append',
2066 help=self.__stripSpaces(self.namespaceVisibilityMap.__doc__ + ' This option adds the namespace as a private archive member.'))
2067 group.add_option('--default-namespace-public',
2068 action="store_true", dest='default_namespace_public',
2069 help=self.__stripSpaces(self.defaultNamespacePublic.__doc__ + ' This option makes the default C{public} (I{default}).'))
2070 group.add_option('--default-namespace-private',
2071 action="store_false", dest='default_namespace_public',
2072 help=self.__stripSpaces(self.defaultNamespacePublic.__doc__ + ' This option makes the default C{private}.'))
2073 parser.add_option_group(group)
2074
2075 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.")
2076 group.add_option('--validate-changes',
2077 action='store_true', dest='validate_changes',
2078 help=self.__stripSpaces(self.validateChanges.__doc__ + ' This option turns on validation (default).'))
2079 group.add_option('--no-validate-changes',
2080 action='store_false', dest='validate_changes',
2081 help=self.__stripSpaces(self.validateChanges.__doc__ + ' This option turns off validation.'))
2082 parser.add_option_group(group)
2083
2084 group = optparse.OptionGroup(parser, 'Miscellaneous Options', "Anything else.")
2085 group.add_option('--logging-config-file', metavar="FILE",
2086 help=self.__stripSpaces(self.loggingConfigFile.__doc__))
2087 parser.add_option_group(group)
2088
2089 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.")
2090
2091 group.add_option('--allow-absent-module',
2092 action='store_true', dest='allow_absent_module',
2093 help=self.__stripSpaces(self.allowAbsentModule.__doc__ + ' This option turns on the feature.'))
2094 group.add_option('--no-allow-absent-module',
2095 action='store_false', dest='allow_absent_module',
2096 help=self.__stripSpaces(self.allowAbsentModule.__doc__ + ' This option turns off the feature (default).'))
2097 group.add_option('--allow-builtin-generation',
2098 action='store_true', dest='allow_builtin_generation',
2099 help=self.__stripSpaces(self.allowBuiltinGeneration.__doc__ + ' This option turns on the feature.'))
2100 group.add_option('--no-allow-builtin-generation',
2101 action='store_false', dest='allow_builtin_generation',
2102 help=self.__stripSpaces(self.allowBuiltinGeneration.__doc__ + ' This option turns off the feature (default).'))
2103 parser.add_option_group(group)
2104
2105 self.__optionParser = parser
2106 return self.__optionParser
2107 __optionParser = None
2108
2110 """Return a command line option sequence that could be used to
2111 construct an equivalent configuration.
2112
2113 @note: If you extend the option parser, as is done by
2114 C{pyxbgen}, this may not be able to reconstruct the correct
2115 command line."""
2116 opts = []
2117 module_list = self.moduleList()
2118 schema_list = self.schemaLocationList()
2119 while module_list and schema_list:
2120 ml = module_list.pop(0)
2121 sl = schema_list.pop(0)
2122 if isinstance(sl, tuple):
2123 sl = sl[0]
2124 opts.extend(['--schema-location=' + sl, '--module=' + ml])
2125 for sl in schema_list:
2126 opts.append('--schema-location=' + sl)
2127 if self.schemaRoot() is not None:
2128 opts.append('--schema-root=' + self.schemaRoot())
2129 if self.schemaStrippedPrefix() is not None:
2130 opts.append('--schema-stripped-prefix=%s' + self.schemaStrippedPrefix())
2131 for (pfx, sub) in self.locationPrefixRewriteMap():
2132 opts.append('--location-prefix-rewrite=%s=%s' % (pfx, sub))
2133 if self.modulePrefix() is not None:
2134 opts.append('--module-prefix=' + self.modulePrefix())
2135 opts.append('--binding-root=' + self.bindingRoot())
2136 if self.archivePath() is not None:
2137 opts.append('--archive-path=' + self.archivePath())
2138 for ns in self.noLoadNamespaces():
2139 opts.append('--no-load-namespace=' + ns.uri())
2140 for fps in self.preLoadArchives():
2141 opts.append('--pre-load-archive=' + fps)
2142 if self.archiveToFile() is not None:
2143 opts.append('--archive-to-file=' + self.archiveToFile())
2144 for (ns, visibility) in self.namespaceVisibilityMap():
2145 if visibility:
2146 opts.append('--public-namespace=' + ns.uri())
2147 else:
2148 opts.append('--private-namespace=' + ns.uri())
2149 if self.defaultNamespacePublic():
2150 opts.append('--default-namespace-public')
2151 else:
2152 opts.append('--default-namespace-private')
2153 for (val, opt) in ( (self.validateChanges(), 'validate-changes'),
2154 (self.writeForCustomization(), 'write-for-customization'),
2155 (self.allowAbsentModule(), 'allow-absent-module'),
2156 (self.allowBuiltinGeneration(), 'allow-builtin-generation') ):
2157 if val:
2158 opts.append('--' + opt)
2159 else:
2160 opts.append('--no-' + opt)
2161 if self.uriContentArchiveDirectory() is not None:
2162 opts.append('--uri-content-archive-directory=%s' + self.uriContentArchiveDirectory())
2163 return opts
2164
2170
2172 """Provide a Python module path for the module record.
2173
2174 This is the path by which the module bindings associated with
2175 C{module_record} will be imported.
2176
2177 If a path had already been assigned to the module, it is left
2178 in place.
2179
2180 @param module_record: Information about a collection of related bindings
2181 @type module_record: L{pyxb.namespace.archive.ModuleRecord}
2182
2183 @param module_path: Default path to use
2184 @type module_path: C{str}
2185
2186 @return: C{module_record}
2187 """
2188 if module_record.modulePath() is not None:
2189 return module_record
2190 namespace = module_record.namespace()
2191 if not namespace.isAbsentNamespace():
2192
2193 if (module_path is None) and not (namespace.prefix() is None):
2194 module_path = namespace.prefix()
2195
2196 module_path = self.namespaceModuleMap().get(namespace.uri(), module_path)
2197 if (module_path is not None) and self.modulePrefix():
2198
2199 module_path = '.'.join([self.modulePrefix(), module_path])
2200 module_record.setModulePath(module_path)
2201 return module_record
2202
2203 __didResolveExternalSchema = False
2205 if self.__didResolveExternalSchema and (not reset):
2206 raise pyxb.PyXBException('Cannot resolve external schema multiple times')
2207
2208
2209
2210
2211 required_archives = pyxb.namespace.archive.NamespaceArchive.PreLoadArchives(self.archivePath(), self.preLoadArchives())
2212 for nsa in required_archives:
2213 nsa.readNamespaces()
2214
2215
2216
2217
2218 for ns in self.noLoadNamespaces():
2219 assert isinstance(ns, pyxb.namespace.Namespace)
2220 ns.markNotLoadable()
2221
2222
2223 while self.__schemaLocationList:
2224 sl = self.__schemaLocationList.pop(0)
2225 if isinstance(sl, tuple):
2226 (sl, converter) = sl
2227 else:
2228 converter = None
2229 try:
2230 if converter is None:
2231 schema = xs.schema.CreateFromLocation(absolute_schema_location=self.normalizeSchemaLocation(sl),
2232 generation_uid=self.generationUID(),
2233 uri_content_archive_directory=self.uriContentArchiveDirectory())
2234 else:
2235 schema = converter(self, sl)
2236 self.addSchema(schema)
2237 except pyxb.SchemaUniquenessError, e:
2238 _log.info('Skipped redundant translation of %s defining %s', e.schemaLocation(), e.namespace())
2239 self.addSchema(e.existingSchema())
2240
2241
2242
2243 for schema in self.__schemas:
2244 if isinstance(schema, basestring):
2245 schema = xs.schema.CreateFromDocument(schema, generation_uid=self.generationUID())
2246 origin = schema.originRecord()
2247 assert origin is not None
2248 module_path = None
2249 if self.__moduleList:
2250 module_path = self.__moduleList.pop(0)
2251 self.assignModulePath(origin.moduleRecord(), module_path)
2252 assert schema.targetNamespace() == origin.moduleRecord().namespace()
2253 self.addNamespace(schema.targetNamespace())
2254 self.__didResolveExternalSchema = True
2255
2256
2257 self.__componentGraph = None
2258 self.__componentOrder = None
2259
2283
2285 if reset or (not self.__didResolveExternalSchema):
2286 self.resolveExternalSchema(reset)
2287
2288 bindable_fn = lambda _c: isinstance(_c, xs.structures.ElementDeclaration) or _c.isTypeDefinition()
2289
2290 self.__moduleRecords = set()
2291 all_components = set()
2292 for origin in self.generationUID().associatedObjects():
2293 mr = origin.moduleRecord()
2294 if not (mr in self.__moduleRecords):
2295 self.__moduleRecords.add(mr)
2296 mr.completeGenerationAssociations()
2297 all_components.update(origin.originatedObjects())
2298
2299 namespaces = set()
2300 for mr in self.__moduleRecords:
2301 if mr.namespace().isBuiltinNamespace() and not self.allowBuiltinGeneration():
2302 continue
2303 namespaces.add(mr.namespace())
2304 pyxb.namespace.resolution.ResolveSiblingNamespaces(namespaces)
2305
2306
2307
2308 for ns in self.namespaces():
2309 self.__namespaceVisibilityMap.setdefault(ns, True)
2310
2311
2312
2313
2314 component_graph = self.__graphFromComponents(all_components, True)
2315
2316 binding_components = set(filter(bindable_fn, component_graph.nodes()))
2317 for c in binding_components:
2318 assert bindable_fn(c), 'Unexpected %s in binding components' % (type(c),)
2319 c._setBindingNamespace(c._objectOrigin().moduleRecord().namespace())
2320
2321 component_csets = self.__graphFromComponents(binding_components, False).sccOrder()
2322 component_order = []
2323 for cset in component_csets:
2324 if 1 < len(cset):
2325 errmsg = ["COMPONENT DEPENDENCY LOOP of %d components" % (len(cset),)]
2326 cg = pyxb.utils.utility.Graph()
2327 for c in cset:
2328 assert bindable_fn(c), 'Unexpected %s in list' % (type(c),)
2329 errmsg.append(' ' + c.expandedName())
2330 cg.addNode(c)
2331 for cd in c.bindingRequires(reset=True, include_lax=False):
2332 cg.addEdge(c, cd)
2333 _log.error('\n'.join(errmsg))
2334
2335 relaxed_order = cg.sccOrder()
2336 for rcs in relaxed_order:
2337 assert 1 == len(rcs)
2338 rcs = rcs[0]
2339 if rcs in cset:
2340 component_order.append(rcs)
2341 else:
2342 component_order.extend(cset)
2343
2344 self.__componentGraph = component_graph
2345 self.__componentOrder = component_order
2346
2347 __moduleRecords = None
2348 __componentGraph = None
2349 __componentOrder = None
2350
2352 """The set of L{pyxb.namespace.archive.ModuleRecord} instances
2353 associated with schema processed in this generation
2354 instance.
2355
2356 These should be in one-to-one correspondence with the
2357 namespaces for which bindings are being generated. Multiple
2358 input schemas may contribute to a single module record; all
2359 material in that record is placed in a single binding file.
2360 """
2361 if self.__moduleRecords is None:
2362 self.__resolveComponentDependencies()
2363 return self.__moduleRecords
2364
2369
2374
2376
2377
2378
2379
2380
2381 module_graph = pyxb.utils.utility.Graph()
2382 [ module_graph.addRoot(_mr) for _mr in self.moduleRecords() ]
2383 for (s, t) in self.componentGraph().edges():
2384 module_graph.addEdge(s._objectOrigin().moduleRecord(), t._objectOrigin().moduleRecord())
2385 module_scc_order = module_graph.sccOrder()
2386
2387 record_binding_map = {}
2388 modules = []
2389 nsvm = self.namespaceVisibilityMap()
2390 for mr_scc in module_scc_order:
2391 scc_modules = [ ]
2392 for mr in mr_scc:
2393 mr._setIsPublic(nsvm.get(mr.namespace(), self.defaultNamespacePublic()))
2394 self.assignModulePath(mr)
2395 if (mr.modulePath() is None) and self.generateToFiles():
2396 raise pyxb.BindingGenerationError('No prefix or module name available for %s' % (mr,))
2397 if (not mr.isPublic()) and (mr.modulePath() is not None):
2398 elts = mr.modulePath().split('.')
2399 elts[-1] = '_%s' % (elts[-1],)
2400 mr.setModulePath('.'.join(elts))
2401 nsm = NamespaceModule(self, mr, mr_scc)
2402 record_binding_map[mr] = nsm
2403 scc_modules.append(nsm)
2404
2405 modules.extend(scc_modules)
2406 if 1 < len(mr_scc):
2407 ngm = NamespaceGroupModule(self, scc_modules)
2408 modules.append(ngm)
2409 for nsm in scc_modules:
2410 nsm.setNamespaceGroupModule(ngm)
2411
2412 element_declarations = []
2413 type_definitions = []
2414 for c in self.componentOrder():
2415 if isinstance(c, xs.structures.ElementDeclaration) and c._scopeIsGlobal():
2416
2417 nsm = record_binding_map[c._objectOrigin().moduleRecord()]
2418 nsm.bindComponent(c)
2419 element_declarations.append(c)
2420 elif c.isTypeDefinition():
2421 type_definitions.append(c)
2422 else:
2423
2424 pass
2425
2426 simple_type_definitions = []
2427 complex_type_definitions = []
2428 for td in type_definitions:
2429 nsm = record_binding_map[td._objectOrigin().moduleRecord()]
2430 assert nsm is not None, 'No namespace module for %s type %s scope %s namespace %s' % (td.expandedName(), type(td), td._scope(), td.bindingNamespace)
2431 module_context = nsm.bindComponent(td)
2432 assert isinstance(module_context, _ModuleNaming_mixin), 'Unexpected type %s' % (type(module_context),)
2433 if isinstance(td, xs.structures.SimpleTypeDefinition):
2434 _PrepareSimpleTypeDefinition(td, self, nsm, module_context)
2435 simple_type_definitions.append(td)
2436 elif isinstance(td, xs.structures.ComplexTypeDefinition):
2437 _PrepareComplexTypeDefinition(td, self, nsm, module_context)
2438 complex_type_definitions.append(td)
2439 else:
2440 assert False, 'Unexpected component type %s' % (type(td),)
2441
2442 for ngm in modules:
2443 if isinstance(ngm, NamespaceGroupModule):
2444 for m in ngm.namespaceModules():
2445 m.addImportsFrom(ngm)
2446
2447 for std in simple_type_definitions:
2448 GenerateSTD(std, self)
2449 for ctd in complex_type_definitions:
2450 GenerateCTD(ctd, self)
2451 for ed in element_declarations:
2452 GenerateED(ed, self)
2453
2454 self.__bindingModules = modules
2455
2456 __bindingModules = None
2463
2479
2482