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 nfa
35
36 import types
37 import sys
38 import traceback
39 import xml.dom
40 import os.path
41 import StringIO
42
43
44
45 UniqueInBinding = set([ 'pyxb', 'sys', 'Namespace', 'ModuleRecord', 'CreateFromDocument', 'CreateFromDOM' ])
55
57 """Base class for something that requires fairly complex activity
58 in order to generate its literal value."""
59
60
61
62 __ownerClass = None
63
64
65 __literal = None
66
70
74
77
82
98
100 __wildcard = None
101
103 self.__wildcard = wildcard
104 super(ReferenceWildcard, self).__init__(**kw)
105
106 template_map = { }
107 template_map['Wildcard'] = 'pyxb.binding.content.Wildcard'
108 if (xs.structures.Wildcard.NC_any == wildcard.namespaceConstraint()):
109 template_map['nc'] = templates.replaceInText('%{Wildcard}.NC_any', **template_map)
110 elif isinstance(wildcard.namespaceConstraint(), (set, frozenset)):
111 namespaces = []
112 for ns in wildcard.namespaceConstraint():
113 if ns is None:
114 namespaces.append(None)
115 else:
116 namespaces.append(ns.uri())
117 template_map['nc'] = 'set(%s)' % (",".join( [ repr(_ns) for _ns in namespaces ]))
118 else:
119 assert isinstance(wildcard.namespaceConstraint(), tuple)
120 ns = wildcard.namespaceConstraint()[1]
121 if ns is not None:
122 ns = ns.uri()
123 template_map['nc'] = templates.replaceInText('(%{Wildcard}.NC_not, %{namespace})', namespace=repr(ns), **template_map)
124 template_map['pc'] = wildcard.processContents()
125 self.setLiteral(templates.replaceInText('%{Wildcard}(process_contents=%{Wildcard}.PC_%{pc}, namespace_constraint=%{nc})', **template_map))
126
136
146
153
161
163 enumerationElement = None
164
166
167
168
169
170
171
172
173
174 value = kw.get('enum_value', None)
175 assert (value is None) or isinstance(value, facets._Enumeration_mixin)
176
177
178
179 facet_instance = kw.get('facet_instance', None)
180 if facet_instance is None:
181 assert isinstance(value, facets._Enumeration_mixin)
182 facet_instance = value._CF_enumeration
183 assert isinstance(facet_instance, facets.CF_enumeration)
184
185
186
187 self.enumerationElement = kw.get('enumeration_element', None)
188 if self.enumerationElement is None:
189 assert value is not None
190 self.enumerationElement = facet_instance.elementForValue(value)
191 assert isinstance(self.enumerationElement, facets._EnumerationElement)
192 if self.enumerationElement.tag() is None:
193 self.enumerationElement._setTag(utility.MakeIdentifier(self.enumerationElement.unicodeValue()))
194 binding_tag = utility.PrepareIdentifier(self.enumerationElement.tag(), kw['class_unique'], kw['class_keywords'])
195 if self.enumerationElement.bindingTag() is None:
196
197
198 self.enumerationElement._setBindingTag(binding_tag)
199
200
201
202 kw.setdefault('type_definition', facet_instance.valueDatatype())
203
204 super(ReferenceEnumerationMember, self).__init__(**kw)
205
206 self.setLiteral(self._addTypePrefix(binding_tag, **kw))
207
209
210 if isinstance(value, types.DictionaryType):
211 return ', '.join([ '%s=%s' % (k, pythonLiteral(v, **kw)) for (k, v) in value.items() ])
212
213
214 if isinstance(value, types.ListType):
215 return [ pythonLiteral(_v, **kw) for _v in value ]
216
217
218 if isinstance(value, pyxb.namespace.ExpandedName):
219 return pythonLiteral(ReferenceExpandedName(expanded_name=value, **kw))
220
221
222 if isinstance(value, (types.TupleType, set)):
223 return type(value)(pythonLiteral(list(value), **kw))
224
225
226
227 if isinstance(value, facets._Enumeration_mixin):
228 return pythonLiteral(ReferenceEnumerationMember(enum_value=value, **kw))
229
230
231
232
233 if isinstance(value, basis.simpleTypeDefinition):
234 return PrefixModule(value, value.pythonLiteral())
235
236 if isinstance(value, pyxb.namespace.Namespace):
237 return pythonLiteral(ReferenceNamespace(namespace=value, **kw))
238
239 if isinstance(value, type):
240 if issubclass(value, basis.simpleTypeDefinition):
241 return PrefixModule(value)
242 if issubclass(value, facets.Facet):
243 return PrefixModule(value)
244
245
246 if isinstance(value, types.StringTypes):
247 return utility.QuotedEscaped(value,)
248
249 if isinstance(value, facets.Facet):
250 return pythonLiteral(ReferenceFacet(facet=value, **kw))
251
252
253 if isinstance(value, facets._PatternElement):
254 return pythonLiteral(value.pattern)
255
256
257 if isinstance(value, facets._EnumerationElement):
258 return pythonLiteral(value.value())
259
260
261 if isinstance(value, xs.structures.Particle):
262 return pythonLiteral(ReferenceParticle(value, **kw))
263
264
265 if isinstance(value, xs.structures.Wildcard):
266 return pythonLiteral(ReferenceWildcard(value, **kw))
267
268
269 if isinstance(value, xs.structures._SchemaComponent_mixin):
270 return pythonLiteral(ReferenceSchemaComponent(value, **kw))
271
272
273 if isinstance(value, ReferenceLiteral):
274 return value.asLiteral()
275
276
277 if isinstance(value, pyxb.namespace.Namespace):
278 return repr(value.uri())
279
280
281 if isinstance(value, (types.NoneType, types.BooleanType, types.FloatType, types.IntType, types.LongType)):
282 return repr(value)
283
284 raise Exception('Unexpected literal type %s' % (type(value),))
285 print 'Unexpected literal type %s' % (type(value),)
286 return str(value)
287
290 mga_tag = '__AModelGroup'
291 template_map['mga_tag'] = mga_tag
292 lines = []
293 lines2 = []
294 for ( dfa, is_required ) in mga.particles():
295 ( dfa_tag, dfa_lines ) = GenerateContentModel(ctd, dfa, binding_module, **kw)
296 lines.extend(dfa_lines)
297 template_map['dfa_tag'] = dfa_tag
298 template_map['is_required'] = binding_module.literal(is_required, **kw)
299 lines2.append(templates.replaceInText(' %{content}.ModelGroupAllAlternative(%{ctd}.%{dfa_tag}, %{is_required}),', **template_map))
300 lines.append(templates.replaceInText('%{mga_tag} = %{content}.ModelGroupAll(alternatives=[', **template_map))
301 lines.extend(lines2)
302 lines.append('])')
303 return (mga_tag, lines)
304
305 -def GenerateContentModel (ctd, automaton, binding_module, **kw):
306 cmi = None
307 template_map = { }
308 template_map['ctd'] = binding_module.literal(ctd, **kw)
309 try:
310 cmi = '_ContentModel_%d' % (ctd.__contentModelIndex,)
311 ctd.__contentModelIndex += 1
312 except AttributeError:
313 cmi = '_ContentModel'
314 ctd.__contentModelIndex = 1
315 template_map['cm_tag'] = cmi
316 template_map['content'] = 'pyxb.binding.content'
317 template_map['state_comma'] = ' '
318 lines = []
319 lines2 = []
320 for (state, transitions) in automaton.items():
321 if automaton.end() == state:
322 continue
323 template_map['state'] = binding_module.literal(state)
324 template_map['is_final'] = binding_module.literal(None in transitions)
325
326 lines2.append(templates.replaceInText('%{state_comma} %{state} : %{content}.ContentModelState(state=%{state}, is_final=%{is_final}, transitions=[', **template_map))
327 template_map['state_comma'] = ','
328 lines3 = []
329 for (key, destinations) in transitions.items():
330 if key is None:
331 continue
332 assert 1 == len(destinations)
333 template_map['next_state'] = binding_module.literal(list(destinations)[0], **kw)
334 if isinstance(key, xs.structures.Wildcard):
335 template_map['kw_key'] = 'term'
336 template_map['kw_val'] = binding_module.literal(key, **kw)
337 elif isinstance(key, nfa.AllWalker):
338 (mga_tag, mga_defns) = GenerateModelGroupAll(ctd, key, binding_module, template_map.copy(), **kw)
339 template_map['kw_key'] = 'term'
340 template_map['kw_val'] = mga_tag
341 lines.extend(mga_defns)
342 else:
343 assert isinstance(key, xs.structures.ElementDeclaration)
344 template_map['kw_key'] = 'element_use'
345 template_map['kw_val'] = templates.replaceInText('%{ctd}._UseForTag(%{field_tag})', field_tag=binding_module.literal(key.expandedName(), **kw), **template_map)
346 lines3.append(templates.replaceInText('%{content}.ContentModelTransition(next_state=%{next_state}, %{kw_key}=%{kw_val}),',
347 **template_map))
348 lines2.extend([ ' '+_l for _l in lines3 ])
349 lines2.append("])")
350
351 lines.append(templates.replaceInText('%{ctd}.%{cm_tag} = %{content}.ContentModel(state_map = {', **template_map))
352 lines.extend([' '+_l for _l in lines2 ])
353 lines.append("})")
354 return (cmi, lines)
355
373
375 binding_module = kw['binding_module']
376 outf = binding_module.bindingIO()
377 facet_instances = []
378 gen_enum_tag = _useEnumerationTags(td)
379 for (fc, fi) in td.facets().items():
380
381
382 if (fi is None) and (fc in td.baseTypeDefinition().facets()):
383
384
385 continue
386 if (fi is not None) and (fi.ownerTypeDefinition() != td):
387
388
389 continue
390 argset = { }
391 is_collection = issubclass(fc, facets._CollectionFacet_mixin)
392 if issubclass(fc, facets._LateDatatype_mixin):
393 vdt = td
394 if fc.LateDatatypeBindsSuperclass():
395 vdt = vdt.baseTypeDefinition()
396 argset['value_datatype'] = vdt
397 if fi is not None:
398 if not is_collection:
399 argset['value'] = fi.value()
400 if isinstance(fi, facets.CF_enumeration):
401 argset['enum_prefix'] = fi.enumPrefix()
402 facet_var = ReferenceFacetMember(type_definition=td, facet_class=fc, **kw)
403 outf.write("%s = %s(%s)\n" % binding_module.literal( (facet_var, fc, argset ), **kw))
404 facet_instances.append(binding_module.literal(facet_var, **kw))
405 if (fi is not None) and is_collection:
406 for i in fi.items():
407 if isinstance(i, facets._EnumerationElement):
408 enum_config = '%s.addEnumeration(unicode_value=%s)' % binding_module.literal( ( facet_var, i.unicodeValue() ), **kw)
409 if gen_enum_tag:
410 enum_member = ReferenceEnumerationMember(type_definition=td, facet_instance=fi, enumeration_element=i, **kw)
411 outf.write("%s = %s\n" % (binding_module.literal(enum_member, **kw), enum_config))
412 if fi.enumPrefix() is not None:
413 outf.write("%s_%s = %s\n" % (fi.enumPrefix(), i.tag(), binding_module.literal(enum_member, **kw)))
414 else:
415 outf.write("%s\n" % (enum_config,))
416 if isinstance(i, facets._PatternElement):
417 outf.write("%s.addPattern(pattern=%s)\n" % binding_module.literal( (facet_var, i.pattern ), **kw))
418 if gen_enum_tag and (xs.structures.SimpleTypeDefinition.VARIETY_union == td.variety()):
419
420
421 fi = td.facets().get(facets.CF_enumeration)
422 if fi is None:
423
424 for mtd in td.memberTypeDefinitions():
425 if not _useEnumerationTags(mtd):
426 continue
427 fi = mtd.facets().get(facets.CF_enumeration)
428 if fi is None:
429 continue
430 for i in fi.items():
431 assert isinstance(i, facets._EnumerationElement)
432 etd = i.enumeration().ownerTypeDefinition()
433 enum_member = ReferenceEnumerationMember(type_definition=td, facet_instance=fi, enumeration_element=i, **kw)
434 outf.write("%-50s%s\n" % ('%s = %s' % binding_module.literal( (enum_member, i.unicodeValue()) ),
435 '# originally %s.%s' % (binding_module.literal(etd), i.bindingTag())))
436 if 2 <= len(facet_instances):
437 map_args = ",\n ".join(facet_instances)
438 else:
439 map_args = ','.join(facet_instances)
440 outf.write("%s._InitializeFacetMap(%s)\n" % (binding_module.literal(td, **kw), map_args))
441
443
444 binding_module = generator.moduleForComponent(std)
445 outf = binding_module.bindingIO()
446
447 class_keywords = frozenset(basis.simpleTypeDefinition._ReservedSymbols)
448 class_unique = set()
449
450 kw = { }
451 kw['binding_module'] = binding_module
452 kw['class_keywords'] = class_keywords
453 kw['class_unique'] = class_unique
454
455 parent_classes = [ binding_module.literal(std.baseTypeDefinition(), **kw) ]
456 enum_facet = std.facets().get(facets.CF_enumeration, None)
457 if (enum_facet is not None) and (enum_facet.ownerTypeDefinition() == std):
458 parent_classes.append('pyxb.binding.basis.enumeration_mixin')
459
460 template_map = { }
461 template_map['std'] = binding_module.literal(std, **kw)
462 template_map['superclasses'] = ''
463 if 0 < len(parent_classes):
464 template_map['superclasses'] = ', '.join(parent_classes)
465 template_map['expanded_name'] = binding_module.literal(std.expandedName(), **kw)
466 template_map['namespaceReference'] = binding_module.literal(std.bindingNamespace(), **kw)
467 if std.annotation() is not None:
468 template_map['documentation'] = std.annotation().asDocString()
469 template_map['documentation_expr'] = binding_module.literal(std.annotation().text())
470 else:
471 template_map['documentation'] = ''
472 template_map['documentation_expr'] = binding_module.literal(None)
473
474
475
476 common_template = '''
477 """%{documentation}"""
478
479 _ExpandedName = %{expanded_name}
480 _Documentation = %{documentation_expr}
481 '''
482 if xs.structures.SimpleTypeDefinition.VARIETY_absent == std.variety():
483 template = '''
484 # The ur SimpleTypeDefinition
485 class %{std} (%{superclasses}):
486 ''' + common_template
487 if not template_map['documentation']:
488 template_map['documentation'] = 'The ur simple type.'
489 elif xs.structures.SimpleTypeDefinition.VARIETY_atomic == std.variety():
490 template = '''
491 # Atomic SimpleTypeDefinition
492 class %{std} (%{superclasses}):
493 ''' + common_template
494 if not template_map['documentation']:
495 template_map['documentation'] = 'An atomic simple type.'
496 elif xs.structures.SimpleTypeDefinition.VARIETY_list == std.variety():
497 template = '''
498 # List SimpleTypeDefinition
499 # superclasses %{superclasses}
500 class %{std} (pyxb.binding.basis.STD_list):
501 ''' + common_template + '''
502 _ItemType = %{itemtype}
503 '''
504 template_map['itemtype'] = binding_module.literal(std.itemTypeDefinition(), **kw)
505 if not template_map['documentation']:
506 template_map['documentation'] = templates.replaceInText('Simple type that is a list of %{itemtype}.', **template_map)
507 elif xs.structures.SimpleTypeDefinition.VARIETY_union == std.variety():
508 template = '''
509 # Union SimpleTypeDefinition
510 # superclasses %{superclasses}
511 class %{std} (pyxb.binding.basis.STD_union):
512 ''' + common_template + '''
513 _MemberTypes = ( %{membertypes}, )
514 '''
515 template_map['membertypes'] = ", ".join( [ binding_module.literal(_mt, **kw) for _mt in std.memberTypeDefinitions() ])
516 if not template_map['documentation']:
517 template_map['documentation'] = templates.replaceInText('Simple type that is a union of %{membertypes}.', **template_map)
518 else:
519 raise pyxb.LogicError("Unhandled STD variety")
520
521 outf.write(templates.replaceInText(template, **template_map))
522
523 generate_facets = False
524 if generate_facets:
525
526 if std.isBuiltin():
527 GenerateFacets(std, generator, **kw)
528 else:
529 GenerateFacets(std, generator, **kw)
530
531 if std.name() is not None:
532 outf.write(templates.replaceInText("%{namespaceReference}.addCategoryObject('typeBinding', %{localName}, %{std})\n",
533 localName=binding_module.literal(std.name(), **kw), **template_map))
534
536 template_map = { }
537 template_map['name'] = unicode(ed.expandedName())
538 template_map['name_expr'] = binding_module.literal(ed.expandedName(), **kw)
539 template_map['namespaceReference'] = binding_module.literal(ed.bindingNamespace(), **kw)
540 if (ed.SCOPE_global == ed.scope()):
541 template_map['class'] = binding_module.literal(ed, **kw)
542 template_map['localName'] = binding_module.literal(ed.name(), **kw)
543 template_map['map_update'] = templates.replaceInText("%{namespaceReference}.addCategoryObject('elementBinding', %{localName}, %{class})", **template_map)
544 else:
545 template_map['scope'] = binding_module.literal(ed.scope(), **kw)
546 if ed.annotation() is not None:
547 template_map['documentation'] = binding_module.literal(unicode(ed.annotation()))
548 if ed.abstract():
549 template_map['abstract'] = binding_module.literal(ed.abstract(), **kw)
550 if ed.nillable():
551 template_map['nillable'] = binding_module.literal(ed.nillable(), **kw)
552 if ed.default():
553 template_map['defaultValue'] = binding_module.literal(ed.default(), **kw)
554 template_map['typeDefinition'] = binding_module.literal(ed.typeDefinition(), **kw)
555 if ed.substitutionGroupAffiliation():
556 template_map['substitution_group'] = binding_module.literal(ed.substitutionGroupAffiliation(), **kw)
557 aux_init = []
558 for k in ( 'nillable', 'abstract', 'scope', 'documentation' ):
559 if k in template_map:
560 aux_init.append('%s=%s' % (k, template_map[k]))
561 template_map['element_aux_init'] = ''
562 if 0 < len(aux_init):
563 template_map['element_aux_init'] = ', ' + ', '.join(aux_init)
564
565 return template_map
566
568 binding_module = generator.moduleForComponent(ctd)
569 outf = binding_module.bindingIO()
570
571 content_type = None
572 prolog_template = None
573 template_map = { }
574 template_map['ctd'] = binding_module.literal(ctd, **kw)
575 base_type = ctd.baseTypeDefinition()
576 content_type_tag = ctd._contentTypeTag()
577
578 template_map['base_type'] = binding_module.literal(base_type, **kw)
579 template_map['namespaceReference'] = binding_module.literal(ctd.bindingNamespace(), **kw)
580 template_map['expanded_name'] = binding_module.literal(ctd.expandedName(), **kw)
581 template_map['simple_base_type'] = binding_module.literal(None, **kw)
582 template_map['contentTypeTag'] = content_type_tag
583 template_map['is_abstract'] = repr(not not ctd.abstract())
584
585 need_content = False
586 content_basis = None
587 if (ctd.CT_SIMPLE == content_type_tag):
588 content_basis = ctd.contentType()[1]
589 template_map['simple_base_type'] = binding_module.literal(content_basis, **kw)
590 elif (ctd.CT_MIXED == content_type_tag):
591 content_basis = ctd.contentType()[1]
592 need_content = True
593 elif (ctd.CT_ELEMENT_ONLY == content_type_tag):
594 content_basis = ctd.contentType()[1]
595 need_content = True
596 need_content = False
597
598 prolog_template = '''
599 # Complex type %{ctd} with content type %{contentTypeTag}
600 class %{ctd} (%{superclass}):
601 _TypeDefinition = %{simple_base_type}
602 _ContentTypeTag = pyxb.binding.basis.complexTypeDefinition._CT_%{contentTypeTag}
603 _Abstract = %{is_abstract}
604 _ExpandedName = %{expanded_name}
605 '''
606
607
608
609
610 inherits_from_base = True
611 template_map['superclass'] = binding_module.literal(base_type, **kw)
612 if ctd._isHierarchyRoot():
613 inherits_from_base = False
614 template_map['superclass'] = 'pyxb.binding.basis.complexTypeDefinition'
615 assert base_type.nameInBinding() is not None
616
617
618 class_keywords = frozenset(basis.complexTypeDefinition._ReservedSymbols)
619 class_unique = set()
620
621
622
623
624
625
626
627 element_name_map = { }
628 element_uses = []
629
630 definitions = []
631
632 definitions.append('# Base type is %{base_type}')
633
634
635
636
637
638 if isinstance(content_basis, xs.structures.Particle):
639 plurality_data = content_basis.pluralityData().combinedPlurality()
640
641 outf.postscript().append("\n\n")
642 for (ed, is_plural) in plurality_data.items():
643
644 ef_map = ed._templateMap()
645 if ed.scope() == ctd:
646 ef_map.update(elementDeclarationMap(ed, binding_module, **kw))
647 aux_init = []
648 ef_map['is_plural'] = repr(is_plural)
649 element_uses.append(templates.replaceInText('%{use}.name() : %{use}', **ef_map))
650 if 0 == len(aux_init):
651 ef_map['aux_init'] = ''
652 else:
653 ef_map['aux_init'] = ', ' + ', '.join(aux_init)
654 ef_map['element_binding'] = utility.PrepareIdentifier('%s_elt' % (ef_map['id'],), class_unique, class_keywords, private=True)
655 if ed.annotation() is not None:
656 ef_map['documentation'] = binding_module.literal(unicode(ed.annotation()))
657 else:
658 ef_map['documentation'] = binding_module.literal(None)
659 if ed.scope() != ctd:
660 definitions.append(templates.replaceInText('''
661 # Element %{id} (%{name}) inherited from %{decl_type_en}''', decl_type_en=unicode(ed.scope().expandedName()), **ef_map))
662 continue
663
664 if ed.expandedName().localName() != ef_map['id']:
665 print 'Element %s.%s renamed to %s' % (ctd.expandedName(), ed.expandedName(), ef_map['id'])
666 definitions.append(templates.replaceInText('''
667 # Element %{name} uses Python identifier %{id}
668 %{use} = pyxb.binding.content.ElementUse(%{name_expr}, '%{id}', '%{key}', %{is_plural}%{aux_init})
669 ''', **ef_map))
670
671 if basis.BINDING_STYLE_ACCESSOR == generator.bindingStyle():
672 definitions.append(templates.replaceInText('''
673 def %{inspector} (self):
674 """Get the value of the %{name} element."""
675 return self.%{use}.value(self)
676 def %{mutator} (self, new_value):
677 """Set the value of the %{name} element. Raises BadValueTypeException
678 if the new value is not consistent with the element's type."""
679 return self.%{use}.set(self, new_value)''', **ef_map))
680 if is_plural:
681 definitions.append(templates.replaceInText('''
682 def %{appender} (self, new_value):
683 """Add the value as another occurrence of the %{name} element. Raises
684 BadValueTypeException if the new value is not consistent with the
685 element's type."""
686 return self.%{use}.append(self, new_value)''', **ef_map))
687 elif basis.BINDING_STYLE_PROPERTY == generator.bindingStyle():
688 definitions.append(templates.replaceInText('''
689 %{inspector} = property(%{use}.value, %{use}.set, None, %{documentation})
690 ''', **ef_map))
691 else:
692 raise pyxb.LogicError('Unexpected binding style %s' % (generator.bindingStyle(),))
693 outf.postscript().append(templates.replaceInText('''
694 %{ctd}._AddElement(pyxb.binding.basis.element(%{name_expr}, %{typeDefinition}%{element_aux_init}))
695 ''', ctd=template_map['ctd'], **ef_map))
696
697 fa = nfa.Thompson(content_basis).nfa()
698 fa = fa.buildDFA()
699 (cmi, cmi_defn) = GenerateContentModel(ctd=ctd, automaton=fa, binding_module=binding_module, **kw)
700 outf.postscript().append("\n".join(cmi_defn))
701 outf.postscript().append("\n")
702
703 if need_content:
704 PostscriptItems.append(templates.replaceInText('''
705 %{ctd}._Content = %{particle}
706 ''', **template_map))
707
708
709 attribute_uses = []
710
711
712
713
714
715
716
717
718 for au in ctd.attributeUses():
719 ad = au.attributeDeclaration()
720 assert isinstance(ad.scope(), xs.structures.ComplexTypeDefinition), 'unexpected scope %s' % (ad.scope(),)
721 au_map = ad._templateMap()
722 if ad.scope() == ctd:
723 assert isinstance(au_map, dict)
724 if au.restrictionOf() is not None:
725
726 au_map = au.restrictionOf().attributeDeclaration()._templateMap().copy()
727 definitions.append(templates.replaceInText('''
728 # Attribute %{id} is restricted from parent''', **au_map))
729
730 assert ad.typeDefinition() is not None
731 au_map['attr_type'] = binding_module.literal(ad.typeDefinition(), **kw)
732
733 vc_source = ad
734 if au.valueConstraint() is not None:
735 vc_source = au
736 aux_init = []
737 if vc_source.fixed() is not None:
738 aux_init.append('fixed=True')
739 aux_init.append('unicode_default=%s' % (binding_module.literal(vc_source.fixed(), **kw),))
740 elif vc_source.default() is not None:
741 aux_init.append('unicode_default=%s' % (binding_module.literal(vc_source.default(), **kw),))
742 if au.required():
743 aux_init.append('required=True')
744 if au.prohibited():
745 aux_init.append('prohibited=True')
746 if 0 == len(aux_init):
747 au_map['aux_init'] = ''
748 else:
749 aux_init.insert(0, '')
750 au_map['aux_init'] = ', '.join(aux_init)
751 if ad.annotation() is not None:
752 au_map['documentation'] = binding_module.literal(unicode(ad.annotation()))
753 else:
754 au_map['documentation'] = binding_module.literal(None)
755 if ad.scope() != ctd:
756 definitions.append(templates.replaceInText('''
757 # Attribute %{id} inherited from %{decl_type_en}''', decl_type_en=unicode(ad.scope().expandedName()), **au_map))
758 continue
759
760 attribute_uses.append(templates.replaceInText('%{use}.name() : %{use}', **au_map))
761 if ad.expandedName().localName() != au_map['id']:
762 print 'Attribute %s.%s renamed to %s' % (ctd.expandedName(), ad.expandedName(), au_map['id'])
763 definitions.append(templates.replaceInText('''
764 # Attribute %{name} uses Python identifier %{id}
765 %{use} = pyxb.binding.content.AttributeUse(%{name_expr}, '%{id}', '%{key}', %{attr_type}%{aux_init})''', **au_map))
766 if au.prohibited():
767 if basis.BINDING_STYLE_ACCESSOR == generator.bindingStyle():
768 definitions.append(templates.replaceInText('''
769 # Attribute %{id} marked prohibited in this type
770 def %{inspector} (self):
771 raise pyxb.ProhibitedAttributeError("Attribute %{name} is prohibited in %{ctd}")
772 def %{mutator} (self, new_value):
773 raise pyxb.ProhibitedAttributeError("Attribute %{name} is prohibited in %{ctd}")
774 ''', ctd=template_map['ctd'], **au_map))
775 elif basis.BINDING_STYLE_PROPERTY == generator.bindingStyle():
776 definitions.append(templates.replaceInText('''
777 %{inspector} = property()
778 ''', ctd=template_map['ctd'], **au_map))
779
780 else:
781 raise pyxb.LogicError('Unexpected binding style %s' % (generator.bindingStyle(),))
782 else:
783 if basis.BINDING_STYLE_ACCESSOR == generator.bindingStyle():
784 definitions.append(templates.replaceInText('''
785 def %{inspector} (self):
786 """Get the attribute value for %{name}."""
787 return self.%{use}.value(self)
788 def %{mutator} (self, new_value):
789 """Set the attribute value for %{name}. Raises BadValueTypeException
790 if the new value is not consistent with the attribute's type."""
791 return self.%{use}.set(self, new_value)''', **au_map))
792 elif basis.BINDING_STYLE_PROPERTY == generator.bindingStyle():
793 definitions.append(templates.replaceInText('''
794 %{inspector} = property(%{use}.value, %{use}.set, None, %{documentation})
795 ''', ctd=template_map['ctd'], **au_map))
796 else:
797 raise pyxb.LogicError('Unexpected binding style %s' % (generator.bindingStyle(),))
798
799 if ctd.attributeWildcard() is not None:
800 definitions.append('_AttributeWildcard = %s' % (binding_module.literal(ctd.attributeWildcard(), **kw),))
801 if ctd.hasWildcardElement():
802 definitions.append('_HasWildcardElement = True')
803 template_map['attribute_uses'] = ",\n ".join(attribute_uses)
804 template_map['element_uses'] = ",\n ".join(element_uses)
805 if inherits_from_base:
806 map_decl = '''
807 _ElementMap = %{superclass}._ElementMap.copy()
808 _ElementMap.update({
809 %{element_uses}
810 })
811 _AttributeMap = %{superclass}._AttributeMap.copy()
812 _AttributeMap.update({
813 %{attribute_uses}
814 })'''
815 else:
816 map_decl = '''
817 _ElementMap = {
818 %{element_uses}
819 }
820 _AttributeMap = {
821 %{attribute_uses}
822 }'''
823
824 template_map['registration'] = ''
825 if ctd.name() is not None:
826 template_map['registration'] = templates.replaceInText("%{namespaceReference}.addCategoryObject('typeBinding', %{localName}, %{ctd})",
827 localName=binding_module.literal(ctd.name(), **kw), **template_map)
828
829 template = ''.join([prolog_template,
830 " ", "\n ".join(definitions), "\n",
831 map_decl, '''
832 %{registration}
833
834 '''])
835
836 outf.write(template, **template_map)
837
839
840 assert ed._scopeIsGlobal()
841
842 binding_module = generator.moduleForComponent(ed)
843 outf = binding_module.bindingIO()
844
845 template_map = elementDeclarationMap(ed, binding_module, **kw)
846 template_map.setdefault('scope', binding_module.literal(None, **kw))
847 template_map.setdefault('map_update', '')
848
849 outf.write(templates.replaceInText('''
850 %{class} = pyxb.binding.basis.element(%{name_expr}, %{typeDefinition}%{element_aux_init})
851 %{namespaceReference}.addCategoryObject('elementBinding', %{class}.name().localName(), %{class})
852 ''', **template_map))
853
854 if ed.substitutionGroupAffiliation() is not None:
855 outf.postscript().append(templates.replaceInText('''
856 %{class}._setSubstitutionGroup(%{substitution_group})
857 ''', **template_map))
858
872
894
896 use_map = component._templateMap()
897 class_unique = nsm.uniqueInClass(container)
898 assert isinstance(component, xs.structures._ScopedDeclaration_mixin)
899 unique_name = utility.PrepareIdentifier(component.expandedName().localName(), class_unique)
900 use_map['id'] = unique_name
901 use_map['inspector'] = unique_name
902 use_map['mutator'] = utility.PrepareIdentifier('set' + unique_name[0].upper() + unique_name[1:], class_unique)
903 use_map['use'] = utility.MakeUnique('__' + unique_name.strip('_'), class_unique)
904 assert component._scope() == container
905 assert component.nameInBinding() is None, 'Use %s but binding name %s for %s' % (use_map['use'], component.nameInBinding(), component.expandedName())
906 component.setNameInBinding(use_map['use'])
907 key_name = '%s_%s_%s' % (str(nsm.namespace()), container.nameInBinding(), component.expandedName())
908 use_map['key'] = utility.PrepareIdentifier(key_name, class_unique, private=True)
909 use_map['name'] = unicode(component.expandedName())
910 use_map['name_expr'] = binding_module.literal(component.expandedName(), **kw)
911 if isinstance(component, xs.structures.ElementDeclaration) and is_plural:
912 use_map['appender'] = utility.PrepareIdentifier('add' + unique_name[0].upper() + unique_name[1:], class_unique)
913 return use_map
914
967
969 __anonSTDIndex = None
970 __anonCTDIndex = None
971 __uniqueInModule = None
972 __uniqueInClass = None
973
974
975 _UniqueInModule = set([ 'pyxb', 'sys' ])
976
977 __ComponentBindingModuleMap = {}
978
981 __generator = None
982
983 - def __init__ (self, generator, *args, **kw):
997
1005
1023
1024 __referencedNamespaces = None
1025
1027 return self.__bindingIO
1028
1029 __moduleUID = None
1034
1036 return str(id(self))
1037
1038 - def moduleContents (self):
1039 template_map = {}
1040 aux_imports = []
1041 for ns in self.__importedModules:
1042 if isinstance(ns, NamespaceModule):
1043 ns = ns.moduleRecord()
1044 module_path = ns.modulePath()
1045 assert module_path is not None, 'No module path for %s type %s' % (ns, type(ns))
1046 aux_imports.append('import %s' % (module_path,))
1047 template_map['aux_imports'] = "\n".join(aux_imports)
1048 template_map['namespace_decls'] = "\n".join(self.__namespaceDeclarations)
1049 template_map['module_uid'] = self.moduleUID()
1050 template_map['generation_uid_expr'] = repr(self.generator().generationUID())
1051 self._finalizeModuleContents_vx(template_map)
1052 return self.__bindingIO.contents()
1053
1067 __modulePath = None
1068
1071 __bindingFile = None
1072 __bindingFilePath = None
1073
1076
1079
1080 @classmethod
1084
1085 @classmethod
1089
1090 @classmethod
1094 @classmethod
1097 __RecordModuleMap = { }
1098
1118 return self.__componentNameMap.get(component)
1119
1121 assert module_type is None
1122 if NamespaceGroupModule == module_type:
1123 pass
1124 elif NamespaceModule == module_type:
1125 pass
1126 else:
1127 assert module_type is None
1128 return component_module
1129
1148
1150
1151 - def defineNamespace (self, namespace, name, require_unique=True, definition=None, **kw):
1165
1167 rv = self.__referencedNamespaces.get(namespace)
1168 if rv is None:
1169 if namespace.isBuiltinNamespace():
1170 rv = namespace.builtinNamespaceRepresentation()
1171 elif namespace.isUndeclaredNamespace():
1172 rv = namespace.modulePath()
1173 elif isinstance(self, NamespaceModule):
1174 if (self.namespace() == namespace):
1175 rv = 'Namespace'
1176 else:
1177 rv = 'pyxb.namespace.NamespaceForURI(%s)' % (repr(namespace.uri()),)
1178 '''
1179 namespace_module = self.ForNamespace(namespace)
1180 if namespace_module is not None:
1181 self._importModule(namespace_module)
1182 rv = '%s.Namespace' % (namespace_module.modulePath(),)
1183 else:
1184 assert False, 'Unexpected reference to %s' % (namespace,)
1185 #rv = 'pyxb.namespace.NamespaceForURI(%s)' % (repr(namespace.uri()),)
1186 '''
1187 else:
1188 if namespace.prefix():
1189 nsn = 'Namespace_%s' % (namespace.prefix(),)
1190 else:
1191 nsn = 'Namespace'
1192 for im in self.__importedModules:
1193 if isinstance(im, NamespaceModule) and (im.namespace() == namespace):
1194 rv = '%s.Namespace' % (im.modulePath(),)
1195 break
1196 if isinstance(im, NamespaceGroupModule):
1197 irv = im.__referencedNamespaces.get(namespace)
1198 if irv is not None:
1199 rv = self.defineNamespace(namespace, nsn, '%s.%s' % (im.modulePath(), irv), protected=True)
1200 break
1201 if rv is None:
1202 rv = self.defineNamespace(namespace, nsn, protected=True)
1203 assert 0 < len(self.__namespaceDeclarations)
1204 self.__referencedNamespaces[namespace] = rv
1205 return rv
1206
1208 return self.__bindingIO.literal(*args, **kw)
1209
1223
1231
1234 """This class represents a Python module that holds all the
1235 declarations belonging to a specific namespace."""
1236
1239 __namespace = None
1240
1243 __moduleRecord = None
1244
1249 __namespaceGroupModule = None
1250
1251 _UniqueInModule = _ModuleNaming_mixin._UniqueInModule.copy()
1252 _UniqueInModule.update([ 'Namespace', 'CreateFromDOM', 'CreateFromDocument' ])
1253
1256 __namespaceGroupHead = None
1257 __namespaceGroup = None
1258
1261 __components = None
1262
1263 @classmethod
1266 __ComponentModuleMap = { }
1267
1272
1275
1276 - def __init__ (self, generator, module_record, mr_scc, components=None, **kw):
1293
1301
1302 - def _finalizeModuleContents_vx (self, template_map):
1303 self.bindingIO().prolog().append(self.bindingIO().expand('''# %{filePath}
1304 # PyXB bindings for NamespaceModule
1305 # NSM:%{module_uid}
1306 # Generated %{date} by PyXB version %{pyxbVersion}
1307 import pyxb
1308 import pyxb.binding
1309 import pyxb.binding.saxer
1310 import StringIO
1311 import pyxb.utils.utility
1312 import pyxb.utils.domutils
1313 import sys
1314
1315 # Unique identifier for bindings created at the same time
1316 _GenerationUID = %{generation_uid_expr}
1317
1318 # Import bindings for namespaces imported into schema
1319 %{aux_imports}
1320
1321 %{namespace_decls}
1322 ModuleRecord = Namespace.lookupModuleRecordByUID(_GenerationUID, create_if_missing=True)
1323 ModuleRecord._setModule(sys.modules[__name__])
1324
1325 def CreateFromDocument (xml_text, default_namespace=None):
1326 """Parse the given XML and use the document element to create a Python instance."""
1327 if pyxb.XMLStyle_saxer != pyxb._XMLStyle:
1328 dom = pyxb.utils.domutils.StringToDOM(xml_text)
1329 return CreateFromDOM(dom.documentElement)
1330 saxer = pyxb.binding.saxer.make_parser(fallback_namespace=Namespace.fallbackNamespace())
1331 handler = saxer.getContentHandler()
1332 saxer.parse(StringIO.StringIO(xml_text))
1333 instance = handler.rootObject()
1334 return instance
1335
1336 def CreateFromDOM (node, default_namespace=None):
1337 """Create a Python instance from the given DOM node.
1338 The node tag must correspond to an element declaration in this module.
1339
1340 @deprecated: Forcing use of DOM interface is unnecessary; use L{CreateFromDocument}."""
1341 if default_namespace is None:
1342 default_namespace = Namespace.fallbackNamespace()
1343 return pyxb.binding.basis.element.AnyCreateFromDOM(node, _fallback_namespace=default_namespace)
1344
1345 ''', **template_map))
1346
1347 __components = None
1348 __componentBindingName = None
1349
1359
1362
1431
1432
1433 -def GeneratePython (schema_location=None,
1434 schema_text=None,
1435 namespace=None,
1436 module_prefix_elts=[],
1437 **kw):
1448
1449 import optparse
1450 import re
1453 """Configuration and data for a single binding-generation action."""
1454
1455 _DEFAULT_bindingRoot = '.'
1457 """The directory path into which generated bindings will be written.
1458 @rtype: C{str}"""
1459 return self.__bindingRoot
1463 __bindingRoot = None
1464
1474
1477 __generateToFiles = None
1478
1480
1481
1482
1483
1484 module_path = None
1485 if isinstance(module, NamespaceModule):
1486 mr = module.moduleRecord()
1487 if mr is None:
1488 return ('/dev/null', None, None)
1489 if self.generationUID() != mr.generationUID():
1490 return ('/dev/null', None, None)
1491 if not self.generateToFiles():
1492 return ('/dev/null', None, None)
1493 if mr.namespace().isBuiltinNamespace() and (not self.allowBuiltinGeneration()):
1494 return ('/dev/null', None, None)
1495 module_path = mr.modulePath()
1496 assert module_path is not None, 'No path specified for module %s' % (mr,)
1497
1498
1499
1500 module_elts = module_path.split('.')
1501 import_file_path = self.__directoryForModulePath(module_elts)
1502 if self.writeForCustomization():
1503 module_elts.insert(-1, 'raw')
1504 if self.writeForCustomization() and (not os.path.exists(import_file_path)):
1505 raw_module_path = '.'.join(module_elts)
1506 pyxb.utils.utility.OpenOrCreate(import_file_path).write("from %s import *\n" % (raw_module_path,))
1507 binding_file_path = self.__directoryForModulePath(module_elts)
1508 try:
1509 binding_file = pyxb.utils.utility.OpenOrCreate(binding_file_path, tag=module.moduleUID())
1510 except OSError, e:
1511 if errno.EEXIST == e.errno:
1512 raise pyxb.BindingGenerationError('Target file %s for module %s bindings exists with other content' % (binding_file_path, mr))
1513 raise
1514 elif isinstance(module, NamespaceGroupModule):
1515 if not self.generateToFiles():
1516 raise pyxb.BindingGenerationError('Generation of namespace groups requires generate-to-files')
1517 module_elts = []
1518 if self.modulePrefix():
1519 module_elts.extend(self.modulePrefix().split('.'))
1520 if self.writeForCustomization():
1521 module_elts.append('raw')
1522 in_use = set()
1523 while True:
1524 module_elts.append(pyxb.utils.utility.PrepareIdentifier('nsgroup', in_use, protected=True))
1525 try:
1526 binding_file_path = self.__directoryForModulePath(module_elts)
1527 print 'Attempting group at %s' % (binding_file_path,)
1528 binding_file = pyxb.utils.utility.OpenOrCreate(binding_file_path, tag=module.moduleUID())
1529 break
1530 except OSError, e:
1531 if errno.EEXIST != e.errno:
1532 raise
1533 module_elts.pop()
1534 module_path = '.'.join(module_elts)
1535 else:
1536 assert False
1537 if self.generateToFiles():
1538 for n in range(len(module_elts)-1):
1539 sub_path = os.path.join(*module_elts[:1+n])
1540 init_path = os.path.join(sub_path, '__init__.py')
1541 if not os.path.exists(init_path):
1542 file(init_path, 'w')
1543 return (binding_file_path, binding_file, module_path)
1544
1546 """The directory from which entrypoint schemas specified as
1547 relative file paths will be read."""
1548 return self.__schemaRoot
1550 if not schema_root.endswith(os.sep):
1551 schema_root = schema_root + os.sep
1552 self.__schemaRoot = schema_root
1553 return self
1554 __schemaRoot = None
1555
1557 """Optional string that is stripped from the beginning of
1558 schemaLocation values before loading from them.
1559
1560 This applies only to the values of schemaLocation attributes
1561 in C{import} and C{include} elements. Its purpose is to
1562 convert absolute schema locations into relative ones to allow
1563 offline processing when all schema are available in a local
1564 directory. See C{schemaRoot}.
1565 """
1566 return self.__schemaStrippedPrefix
1570 __schemaStrippedPrefix = None
1571
1573 """A list of locations from which entrypoint schemas are to be
1574 read.
1575
1576 The values in the list are either URIs, or tuples consisting
1577 of a value and a callable which, when passed the generator
1578 object and the value, will return a
1579 L{pyxb.xmlschema.structures.Schema} instance. See
1580 L{addSchemaLocation}.
1581
1582 See also L{addSchemaLocation} and L{schemas}.
1583 """
1584 return self.__schemaLocationList
1590 """Add the location of an entrypoint schema.
1591
1592 @param schema_location: The location of the schema. This
1593 should be a URL; if the schema location does not have a URL
1594 scheme (e.g., C{http:}), it is assumed to be a file, and if it
1595 is not an absolute path is located relative to the
1596 C{schemaRoot}.
1597
1598 @keyword converter: Optional callable that will be invoked
1599 with the generator instance and the schema location, and is
1600 expected to return a L{pyxb.xmlschema.structures.Schema}
1601 instance. If absent, the contents of the location are
1602 converted directly.
1603
1604 @note: The C{converter} argument derives from WSDL support: we
1605 need to add to the sequence of schema locations a URI of
1606 something that will not parse as a schema, but does have inner
1607 material that can if treated properly. "Treated properly" may
1608 include having the archive path and other namespace
1609 manipulations configured before anything is done to it.
1610 """
1611 self.__schemaLocationList.append( (schema_location, converter) )
1612 return self
1614 """Add the location of an entrypoint schema. The provided
1615 value should be a URL; if it does not have a URL scheme (e.g.,
1616 C{http:}), it is assumed to be a file, and if it is not an
1617 absolute path is located relative to the C{schemaRoot}."""
1618 self.addSchemaLocation(schema_location)
1619 __schemaLocationList = None
1620
1622 """Schema for which bindings should be generated.
1623
1624 These may be L{Schema<pyxb.xmlschema.structures.Schema>}
1625 instances, or strings; the latter is preferred, and is parsed
1626 into a Schema instance when required.
1627
1628 This is the list of entrypoint schemas for binding generation.
1629 Values in L{schemaLocationList} are read and converted into
1630 schema, then appended to this list. Values from L{moduleList}
1631 are applied starting with the first schema in this list.
1632 """
1633 return self.__schemas[:]
1641 __schemas = None
1642
1644 """The set of L{namespaces<pyxb.namespace.Namespace>} for
1645 which bindings will be generated.
1646
1647 This is the set of namespaces read from entrypoint schema,
1648 closed under reference to namespaces defined by schema import.
1649
1650 @rtype: C{set}
1651 """
1652 return self.__namespaces.copy()
1660 __namespaces = None
1661
1663 """A list of module names to be applied in order to the namespaces of entrypoint schemas"""
1664 return self.__moduleList[:]
1669
1671 """Add a module name corresponding to an entrypoint schema.
1672
1673 The namespace defined by the corresponding schema will be
1674 written to a binding using the given module name, adjusted by
1675 L{modulePrefix}."""
1676 self.__moduleList.append(module_name)
1677 return self
1678 __moduleList = None
1679
1681 """The prefix for binding modules.
1682
1683 The base name for the module holding a binding is taken from
1684 the moduleList, moduleMap, or an XMLNS prefix associated with
1685 the namespace in a containing schema. This value, if present,
1686 is used as a prefix to allow a deeper module hierarchy."""
1687 return self.__modulePrefix
1691 __modulePrefix = None
1692
1694 """A map from namespace URIs to the module to be used for the
1695 corresponding generated binding.
1696
1697 Module values are adjusted by L{modulePrefix} if that has been
1698 specified.
1699
1700 An entry in this map for a namespace supersedes the module
1701 specified in moduleList if the namespace is defined by an
1702 entrypoint schema.
1703
1704 @return: A reference to the namespace module map.
1705 """
1706 return self.__namespaceModuleMap
1707 __namespaceModuleMap = None
1708
1710 """A colon-separated list of paths from which namespace
1711 archives can be read.
1712
1713 The default path is the contents of the C{PYXB_ARCHIVE_PATH}
1714 environment variable, or the standard path configured at
1715 installation time. Any file with the extension C{.wxs} found
1716 in one of these directories is examined to see whether it is a
1717 namespace archive.
1718 """
1719 return self.__archivePath
1723 __archivePath = None
1724
1726 """A frozenset of namespaces that many not be loaded from an archive."""
1727 return frozenset(self.__noLoadNamespaces)
1729 """Record the set of namespaces that should not be loaded from an archive.
1730
1731 The expectation is that any required entities in the namespace
1732 will be defined by loading schema."""
1733 self.__noLoadNamespaces.clear()
1734 self.__noLoadNamespaces.update([ pyxb.namespace.NamespaceInstance(_ns) for _ns in namespace_set ])
1736 """Mark that the specified namespace should not be loaded from an archive.
1737
1738 Use this when you are generating bindings for an application
1739 that has a restricted profile of a namespace that would
1740 otherwise be read from an archive. Be aware that this removes
1741 any knowledge of any archive in which this namespace is
1742 present as a non-private member."""
1743 self.__noLoadNamespaces.add(pyxb.namespace.NamespaceInstance(namespace))
1744 __noloadNamespaces = None
1745
1747 """A list of paths to archives that should be loaded, in order, prior to parsing schema."""
1748 return frozenset(self.__preLoadArchives)
1750 """Name of a file containing a stored archive from which
1751 namespaces should be read prior to processing schema.
1752
1753 Files to be pre-loaded are not affected by
1754 C{noLoadNamespace}."""
1755 self.__preLoadArchives.append(archive_file)
1759 __preLoadArchives = None
1760
1762 """Optional file into which the archive of namespaces will be written.
1763
1764 Subsequent generation actions can read pre-parsed namespaces
1765 from this file, and therefore reference the bindings that were
1766 built earlier rather than re-generating them.
1767
1768 The file name should normally end with C{.wxs}."""
1769 return self.__archiveToFile
1773 __archiveToFile = None
1774
1788 """Indicates, for specific namespaces, whether their
1789 visibility in the archive should be public or private."""
1790 return self.__namespaceVisibilityMap.copy()
1791 __namespaceVisibilityMap = None
1792
1794 """Indicates whether unmentioned namespaces will be public or private (default) in the archive.
1795
1796 A namespace is I{mentioned} if it is the target namespace of
1797 an entrypoint schema, or appears in a namespace visibility
1798 specification. I.e., this default applies only to namespaces
1799 that are modified as a result of including some schema, which
1800 is generally a local customization of something.
1801 """
1802 return self.__defaultNamespacePublic
1805 __defaultNamespacePublic = None
1806
1808 """Indicates whether the bindings should validate mutations
1809 against the content model."""
1810 return self.__validateChanges
1815 __validateChanges = None
1816
1817 _DEFAULT_bindingStyle = basis.CURRENT_BINDING_STYLE
1819 """The style of Python used in generated bindings.
1820
1821 C{accessor} means values are private variables accessed
1822 through inspector and mutator methods.
1823
1824 C{property} means values are private variables accessed
1825 through a Python property.
1826 """
1827 return self.__bindingStyle
1832 __bindingStyle = None
1833
1835 """Indicates whether the binding Python code should be written into a sub-module for customization.
1836
1837 If enabled, a module C{path.to.namespace} will be written to
1838 the file C{path/to/raw/namespace.py}, so that the file
1839 C{path/to/namespace.py} can import it and override behavior."""
1840 return self.__writeForCustomization
1844 __writeForCustomization = None
1845
1847 """Indicates whether the code generator is permitted to
1848 process namespace for which no module path can be determined.
1849
1850 Use this only when generating bindings that will not be
1851 referenced by other bindings."""
1852 return self.__allowAbsentModule
1856 __allowAbsentModule = None
1857
1859 """Indicates whether bindings will be written for namespaces that are built-in to PyXB.
1860
1861 This must be enabled when building bindings for the XML,
1862 XMLSchema instance, and other built-in namespaces. Normally
1863 generation of these namespaces is inhibited lest it produce
1864 inconsistencies."""
1865 return self.__allowBuiltinGeneration
1869 __allowBuiltinGeneration = None
1870
1872 """The directory path into which any content retrieved by URI will be written.
1873
1874 This serves as a local cache, and to give you an opportunity
1875 to inspect material retrieved from some other system.
1876 @rtype: C{str}"""
1877 return self.__uriContentArchiveDirectory
1880 __uriContentArchiveDirectory = None
1881
1883 """Create a configuration to be used for generating bindings.
1884
1885 Arguments are treated as additions to the schema location list
1886 after all keywords have been processed.
1887
1888 @keyword binding_root: Invokes L{setBindingRoot}
1889 @keyword schema_root: Invokes L{setSchemaRoot}
1890 @keyword schema_stripped_prefix: Invokes L{setSchemaStrippedPrefix}
1891 @keyword schema_location_list: Invokes L{setSchemaLocationList}
1892 @keyword module_list: Invokes L{_setModuleList}
1893 @keyword module_prefix: Invokes L{setModulePrefix}
1894 @keyword archive_path: Invokes L{setArchivePath}
1895 @keyword no_load_namespaces: Invokes L{_setNoLoadNamespaces}
1896 @keyword pre_load_archives: Invokes L{_setPreLoadArchives}
1897 @keyword archive_to_file: Invokes L{setArchiveToFile}
1898 @keyword public_namespace: Invokes L{setNamespaceVisibility}
1899 @keyword private_namespace: Invokes L{setNamespaceVisibility}
1900 @keyword default_namespace_public: Invokes L{setDefaultNamespacePublic}
1901 @keyword validate_changes: Invokes L{setValidateChanges}
1902 @keyword binding_style: Invokes L{setBindingStyle}
1903 @keyword namespace_module_map: Initializes L{namespaceModuleMap}
1904 @keyword schemas: Invokes L{setSchemas}
1905 @keyword namespaces: Invokes L{setNamespaces}
1906 @keyword write_for_customization: Invokes L{setWriteForCustomization}
1907 @keyword allow_builtin_generation: Invokes L{setAllowBuiltinGeneration}
1908 @keyword allow_absent_module: Invokes L{setAllowAbsentModule}
1909 @keyword generate_to_files: Sets L{generateToFiles}
1910 @keyword uri_content_archive_directory: Invokes L{setUriContentArchiveDirectory}
1911 """
1912 argv = kw.get('argv', None)
1913 if argv is not None:
1914 kw = {}
1915 self.__bindingRoot = kw.get('binding_root', self._DEFAULT_bindingRoot)
1916 self.__schemaRoot = kw.get('schema_root', '.')
1917 self.__schemaStrippedPrefix = kw.get('schema_stripped_prefix')
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.__bindingStyle = kw.get('binding_style', self._DEFAULT_bindingStyle)
1931 self.__namespaceModuleMap = kw.get('namespace_module_map', {}).copy()
1932 self.__schemas = kw.get('schemas', [])[:]
1933 self.__namespaces = set(kw.get('namespaces', []))
1934 self.__writeForCustomization = kw.get('write_for_customization', False)
1935 self.__writeForCustomization = kw.get('allow_builtin_generation', False)
1936 self.__allowAbsentModule = kw.get('allow_absent_module', False)
1937 self.__generateToFiles = kw.get('generate_to_files', True)
1938 self.__uriContentArchiveDirectory = kw.get('uri_content_archive_directory')
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 ('schema_location', setSchemaLocationList),
1957 ('module', _setModuleList),
1958 ('module_prefix', setModulePrefix),
1959 ('archive_path', setArchivePath),
1960 ('no_load_namespace', _setNoLoadNamespaces),
1961 ('pre_load_archive', _setPreLoadArchives),
1962 ('archive_to_file', setArchiveToFile),
1963 ('default_namespace_public', setDefaultNamespacePublic),
1964 ('binding_style', setBindingStyle),
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 )
1972 for (tag, method) in self.__OptionSetters:
1973 v = getattr(options, tag)
1974 if v is not None:
1975 method(self, v)
1976 public_namespaces = getattr(options, 'public_namespace')
1977 private_namespaces = getattr(options, 'private_namespace')
1978 self._setNamespaceVisibilities(public_namespaces, private_namespaces)
1979 if args is not None:
1980 self.__schemaLocationList.extend(args)
1981
1983 if argv is None:
1984 argv = sys.argv[1:]
1985 (options, args) = self.optionParser().parse_args(argv)
1986 self.applyOptionValues(options, args)
1987 return self
1988
1991 __generationUID = None
1992
1994 """Return an C{optparse.OptionParser} instance tied to this configuration.
1995
1996 @param reset: If C{False} (default), a parser created in a
1997 previous invocation will be returned. If C{True}, any
1998 previous option parser is discarded and a new one created.
1999 @type reset: C{bool}
2000 """
2001 if reset or (self.__optionParser is None):
2002 parser = optparse.OptionParser(usage="%prog [options] [more schema locations...]",
2003 version='%%prog from PyXB %s' % (pyxb.__version__,),
2004 description='Generate bindings from a set of XML schemas')
2005
2006 group = optparse.OptionGroup(parser, 'Identifying Schema', 'Specify and locate schema for which bindings should be generated.')
2007 group.add_option('--schema-location', '-u', metavar="FILE_or_URL",
2008 action='append',
2009 help=self.__stripSpaces(self.argAddSchemaLocation.__doc__))
2010 group.add_option('--schema-root', metavar="DIRECTORY",
2011 help=self.__stripSpaces(self.schemaRoot.__doc__))
2012 group.add_option('--schema-stripped-prefix', metavar="TEXT", type='string',
2013 help=self.__stripSpaces(self.schemaStrippedPrefix.__doc__))
2014 group.add_option('--uri-content-archive-directory', metavar="DIRECTORY",
2015 help=self.__stripSpaces(self.uriContentArchiveDirectory.__doc__))
2016 parser.add_option_group(group)
2017
2018 group = optparse.OptionGroup(parser, 'Configuring Bindings', 'Specify where generated bindings should be written, and how they will be accessed from Python.')
2019 group.add_option('--module', '-m', metavar="MODULE",
2020 action='append',
2021 help=self.__stripSpaces(self.addModuleName.__doc__))
2022 group.add_option('--module-prefix', metavar="MODULE",
2023 help=self.__stripSpaces(self.modulePrefix.__doc__))
2024 group.add_option('--binding-root', metavar="DIRECTORY",
2025 help=self.__stripSpaces(self.bindingRoot.__doc__))
2026 group.add_option('-r', '--write-for-customization',
2027 action='store_true', dest='write_for_customization',
2028 help=self.__stripSpaces(self.writeForCustomization.__doc__ + ' This option turns on the feature.'))
2029 group.add_option('--no-write-for-customization',
2030 action='store_false', dest='write_for_customization',
2031 help=self.__stripSpaces(self.writeForCustomization.__doc__ + ' This option turns off the feature (I{default}).'))
2032 parser.add_option_group(group)
2033
2034 group = optparse.OptionGroup(parser, 'Reading Namespace Archives', 'Locating and loading (or inhibiting load of) namespace archives.')
2035 group.add_option('--archive-path', metavar="PATH",
2036 help=self.__stripSpaces(self.archivePath.__doc__))
2037 group.add_option('--pre-load-archive', metavar="FILE",
2038 action='append',
2039 help=self.__stripSpaces(self.addPreLoadArchive.__doc__))
2040 group.add_option('--no-load-namespace', metavar="URI",
2041 action='append',
2042 help=self.__stripSpaces(self.addNoLoadNamespace.__doc__))
2043 parser.add_option_group(group)
2044
2045 group = optparse.OptionGroup(parser, 'Writing Namespace Archives', 'Control the location and content of a namespace archive corresponding to a binding generation.')
2046 group.add_option('--archive-to-file', metavar="FILE",
2047 help=self.__stripSpaces(self.archiveToFile.__doc__))
2048 group.add_option('--public-namespace', metavar="URI",
2049 action='append',
2050 help=self.__stripSpaces(self.namespaceVisibilityMap.__doc__ + ' This option adds the namespace as a public archive member.'))
2051 group.add_option('--private-namespace', metavar="URI",
2052 action='append',
2053 help=self.__stripSpaces(self.namespaceVisibilityMap.__doc__ + ' This option adds the namespace as a private archive member.'))
2054 group.add_option('--default-namespace-public',
2055 action="store_true", dest='default_namespace_public',
2056 help=self.__stripSpaces(self.defaultNamespacePublic.__doc__ + ' This option makes the default C{public} (I{default}).'))
2057 group.add_option('--default-namespace-private',
2058 action="store_false", dest='default_namespace_public',
2059 help=self.__stripSpaces(self.defaultNamespacePublic.__doc__ + ' This option makes the default C{private}.'))
2060 parser.add_option_group(group)
2061
2062 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.")
2063 group.add_option('--binding-style',
2064 type='choice', choices=basis.BINDING_STYLES,
2065 help=self.__stripSpaces(self.bindingStyle.__doc__))
2066 group.add_option('--validate-changes',
2067 action='store_true', dest='validate_changes',
2068 help=self.__stripSpaces(self.validateChanges.__doc__ + ' This option turns on validation (default).'))
2069 group.add_option('--no-validate-changes',
2070 action='store_false', dest='validate_changes',
2071 help=self.__stripSpaces(self.validateChanges.__doc__ + ' This option turns off validation.'))
2072 parser.add_option_group(group)
2073
2074 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.")
2075 group.add_option('--allow-absent-module',
2076 action='store_true', dest='allow_absent_module',
2077 help=self.__stripSpaces(self.allowAbsentModule.__doc__ + ' This option turns on the feature.'))
2078 group.add_option('--no-allow-absent-module',
2079 action='store_false', dest='allow_absent_module',
2080 help=self.__stripSpaces(self.allowAbsentModule.__doc__ + ' This option turns off the feature (default).'))
2081 group.add_option('--allow-builtin-generation',
2082 action='store_true', dest='allow_builtin_generation',
2083 help=self.__stripSpaces(self.allowBuiltinGeneration.__doc__ + ' This option turns on the feature.'))
2084 group.add_option('--no-allow-builtin-generation',
2085 action='store_false', dest='allow_builtin_generation',
2086 help=self.__stripSpaces(self.allowBuiltinGeneration.__doc__ + ' This option turns off the feature (default).'))
2087 parser.add_option_group(group)
2088
2089 self.__optionParser = parser
2090 return self.__optionParser
2091 __optionParser = None
2092
2094 """Return a command line option sequence that could be used to
2095 construct an equivalent configuration.
2096
2097 @note: If you extend the option parser, as is done by
2098 C{pyxbgen}, this may not be able to reconstruct the correct
2099 command line."""
2100 opts = []
2101 module_list = self.moduleList()
2102 schema_list = self.schemaLocationList()
2103 while module_list and schema_list:
2104 ml = module_list.pop(0)
2105 sl = schema_list.pop(0)
2106 if isinstance(sl, tuple):
2107 sl = sl[0]
2108 opts.extend(['--schema-location=' + sl, '--module=' + ml])
2109 for sl in schema_list:
2110 opts.append('--schema-location=' + sl)
2111 if self.schemaRoot() is not None:
2112 opts.append('--schema-root=' + self.schemaRoot())
2113 if self.schemaStrippedPrefix() is not None:
2114 opts.append('--schema-stripped-prefix=%s' + self.schemaStrippedPrefix())
2115 if self.modulePrefix() is not None:
2116 opts.append('--module-prefix=' + self.modulePrefix())
2117 opts.append('--binding-root=' + self.bindingRoot())
2118 if self.archivePath() is not None:
2119 opts.append('--archive-path=' + self.archivePath())
2120 for ns in self.noLoadNamespaces():
2121 opts.append('--no-load-namespace=' + ns.uri())
2122 for fps in self.preLoadArchives():
2123 opts.append('--pre-load-archive=' + fp)
2124 if self.archiveToFile() is not None:
2125 opts.append('--archive-to-file=' + self.archiveToFile())
2126 for (ns, visibility) in self._namespaceVisibilityMap():
2127 if visibility:
2128 opts.append('--public-namespace=' + ns.uri())
2129 else:
2130 opts.append('--private-namespace=' + ns.uri())
2131 if self.defaultNamespacePublic():
2132 opts.append('--default-namespace-public')
2133 else:
2134 opts.append('--default-namespace-private')
2135 for (val, opt) in ( (self.validateChanges(), 'validate-changes'),
2136 (self.writeForCustomization(), 'write-for-customization'),
2137 (self.allowAbsentModule(), 'allow-absent-module'),
2138 (self.allowBuiltinGeneration(), 'allow-builtin-generation') ):
2139 if val:
2140 opts.append('--' + opt)
2141 else:
2142 opts.append('--no-' + opt)
2143 if self.uriContentArchiveDirectory() is not None:
2144 opts.append('--uri-content-archive-directory=%s' + self.uriContentArchiveDirectory())
2145 return opts
2146
2152
2167
2168 __didResolveExternalSchema = False
2170 if self.__didResolveExternalSchema and (not reset):
2171 raise pyxb.PyXBException('Cannot resolve external schema multiple times')
2172
2173 required_archives = pyxb.namespace.archive.NamespaceArchive.PreLoadArchives(self.archivePath(), self.preLoadArchives())
2174 for nsa in required_archives:
2175 nsa.readNamespaces()
2176 for ns in self.noLoadNamespaces():
2177 assert isinstance(ns, pyxb.namespace.Namespace)
2178 ns.markNotLoadable()
2179 while self.__schemaLocationList:
2180 sl = self.__schemaLocationList.pop(0)
2181 if isinstance(sl, tuple):
2182 (sl, converter) = sl
2183 else:
2184 converter = None
2185 try:
2186 if converter is None:
2187 schema = xs.schema.CreateFromLocation(absolute_schema_location=self.normalizeSchemaLocation(sl), generation_uid=self.generationUID(), uri_content_archive_directory=self.uriContentArchiveDirectory())
2188 else:
2189 schema = converter(self, sl)
2190 self.addSchema(schema)
2191 except pyxb.SchemaUniquenessError, e:
2192 print 'WARNING: Skipped redundant translation of %s defining %s' % (e.schemaLocation(), e.namespace())
2193 self.addSchema(e.existingSchema())
2194 for schema in self.__schemas:
2195 if isinstance(schema, basestring):
2196 schema = xs.schema.CreateFromDocument(schema, generation_uid=self.generationUID())
2197 origin = schema.originRecord()
2198 assert origin is not None
2199 module_path = None
2200 if self.__moduleList:
2201 module_path = self.__moduleList.pop(0)
2202 self.__assignModulePath(origin.moduleRecord(), module_path)
2203 assert schema.targetNamespace() == origin.moduleRecord().namespace()
2204 self.addNamespace(schema.targetNamespace())
2205 self.__didResolveExternalSchema = True
2206 self.__bindingModules = None
2207
2233
2235 named_bindable_fn = lambda _c: (isinstance(_c, xs.structures.ElementDeclaration) and _c._scopeIsGlobal()) or _c.isTypeDefinition()
2236 bindable_fn = lambda _c: isinstance(_c, xs.structures.ElementDeclaration) or _c.isTypeDefinition()
2237
2238 self.__moduleRecords = set()
2239 all_components = set()
2240 for origin in self.generationUID().associatedObjects():
2241 mr = origin.moduleRecord()
2242 if not (mr in self.__moduleRecords):
2243
2244
2245 self.__moduleRecords.add(mr)
2246 mr.completeGenerationAssociations()
2247 all_components.update(origin.originatedObjects())
2248
2249 namespaces = set()
2250 for mr in self.__moduleRecords:
2251 if mr.namespace().isBuiltinNamespace() and not self.allowBuiltinGeneration():
2252 continue
2253 namespaces.add(mr.namespace())
2254 pyxb.namespace.resolution.ResolveSiblingNamespaces(namespaces, self.generationUID())
2255
2256
2257
2258 for ns in self.namespaces():
2259 self.__namespaceVisibilityMap.setdefault(ns, True)
2260
2261
2262
2263
2264 component_graph = self.__graphFromComponents(all_components, True)
2265
2266 binding_components = set(filter(bindable_fn, component_graph.nodes()))
2267
2268
2269
2270 module_graph = pyxb.utils.utility.Graph()
2271 [ module_graph.addRoot(_mr) for _mr in self.__moduleRecords ]
2272 for (s, t) in component_graph.edges():
2273 module_graph.addEdge(s._objectOrigin().moduleRecord(), t._objectOrigin().moduleRecord())
2274 module_scc_order = module_graph.sccOrder()
2275
2276
2277
2278
2279
2280
2281
2282
2283 for c in binding_components:
2284 assert bindable_fn(c), 'Unexpected %s in binding components' % (type(s),)
2285 c._setBindingNamespace(c._objectOrigin().moduleRecord().namespace())
2286
2287 record_binding_map = {}
2288 unique_in_bindings = set([NamespaceGroupModule._GroupPrefix])
2289 modules = []
2290 for mr_scc in module_scc_order:
2291 scc_modules = [ ]
2292 for mr in mr_scc:
2293
2294
2295 mr._setIsPublic(self.__namespaceVisibilityMap.get(mr.namespace(), self.defaultNamespacePublic()))
2296 self.__assignModulePath(mr)
2297 assert not ((mr.modulePath() is None) and self.generateToFiles()), 'No module path defined for %s' % (mr,)
2298 if (not mr.isPublic()) and (mr.modulePath() is not None):
2299 elts = mr.modulePath().split('.')
2300 elts[-1] = '_%s' % (elts[-1],)
2301 mr.setModulePath('.'.join(elts))
2302 nsm = NamespaceModule(self, mr, mr_scc)
2303 record_binding_map[mr] = nsm
2304 scc_modules.append(nsm)
2305
2306 modules.extend(scc_modules)
2307 if 1 < len(mr_scc):
2308 ngm = NamespaceGroupModule(self, scc_modules)
2309 modules.append(ngm)
2310 for nsm in scc_modules:
2311 nsm.setNamespaceGroupModule(ngm)
2312
2313 component_csets = self.__graphFromComponents(binding_components, False).sccOrder()
2314 bad_order = False
2315 component_order = []
2316 for cset in component_csets:
2317 if 1 < len(cset):
2318 print "COMPONENT DEPENDENCY LOOP of %d components" % (len(cset),)
2319 cg = pyxb.utils.utility.Graph()
2320 for c in cset:
2321 assert bindable_fn(c), 'Unexpected %s in list' % (type(c),)
2322 print ' %s' % (c.expandedName(),)
2323 cg.addNode(c)
2324 for cd in c.bindingRequires(reset=True, include_lax=False):
2325
2326 cg.addEdge(c, cd)
2327
2328 relaxed_order = cg.sccOrder()
2329 for rcs in relaxed_order:
2330 assert 1 == len(rcs)
2331 rcs = rcs[0]
2332 if rcs in cset:
2333 component_order.append(rcs)
2334 else:
2335 component_order.extend(cset)
2336
2337
2338
2339 element_declarations = []
2340 type_definitions = []
2341 for c in component_order:
2342 if isinstance(c, xs.structures.ElementDeclaration) and c._scopeIsGlobal():
2343
2344 nsm = record_binding_map[c._objectOrigin().moduleRecord()]
2345 nsm.bindComponent(c)
2346 element_declarations.append(c)
2347 elif c.isTypeDefinition():
2348 type_definitions.append(c)
2349 else:
2350
2351 pass
2352
2353 simple_type_definitions = []
2354 complex_type_definitions = []
2355 for td in type_definitions:
2356 nsm = record_binding_map[td._objectOrigin().moduleRecord()]
2357 assert nsm is not None, 'No namespace module for %s type %s scope %s namespace %s' % (td.expandedName(), type(td), td._scope(), td.bindingNamespace)
2358 module_context = nsm.bindComponent(td)
2359 assert isinstance(module_context, _ModuleNaming_mixin), 'Unexpected type %s' % (type(module_context),)
2360 if isinstance(td, xs.structures.SimpleTypeDefinition):
2361 _PrepareSimpleTypeDefinition(td, self, nsm, module_context)
2362 simple_type_definitions.append(td)
2363 elif isinstance(td, xs.structures.ComplexTypeDefinition):
2364 _PrepareComplexTypeDefinition(td, self, nsm, module_context)
2365 complex_type_definitions.append(td)
2366 else:
2367 assert False, 'Unexpected component type %s' % (type(td),)
2368
2369 for ngm in modules:
2370 if isinstance(ngm, NamespaceGroupModule):
2371 for m in ngm.namespaceModules():
2372 m.addImportsFrom(ngm)
2373
2374 for std in simple_type_definitions:
2375 GenerateSTD(std, self)
2376 for ctd in complex_type_definitions:
2377 GenerateCTD(ctd, self)
2378 for ed in element_declarations:
2379 GenerateED(ed, self)
2380
2381 return modules
2382
2383 __bindingModules = None
2390
2392 archive_file = self.archiveToFile()
2393 if archive_file is not None:
2394 ns_archive = pyxb.namespace.archive.NamespaceArchive(generation_uid=self.generationUID())
2395 try:
2396 ns_archive.writeNamespaces(pyxb.utils.utility.OpenOrCreate(archive_file))
2397 print 'Saved parsed schema to %s URI' % (archive_file,)
2398 except Exception, e:
2399 print 'Exception saving preprocessed schema to %s: %s' % (archive_file, e)
2400 traceback.print_exception(*sys.exc_info())
2401
2402
2403
2404
2405 if isinstance(e, (AssertionError, AttributeError, TypeError)):
2406 raise
2407
2410