1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
# Demonstrate alternatives for bindings customization
# Introspection-based customization.
from raw.custom import *
import raw.custom as raw_custom
class ta04 (raw_custom.ta04):
def xa04 (self):
return 'extend ta04'
raw_custom.ta04._SetSupersedingClass(ta04)
import inspect
# Utility function to identify classes of interest
def _isSupersedable (cls):
return inspect.isclass(cls) and issubclass(cls, pyxb.binding.basis._DynamicCreate_mixin)
def _injectClasses ():
import sys
import pyxb.binding.basis
# All PyXB complex type definitions in the original module
raw_classes = set([_o for (_, _o) in inspect.getmembers(raw_custom) if _isSupersedable(_o)])
#print 'Original classes: %s' % (raw_classes,)
# PyXB complex type definitions in this module that did not come
# from the original import *.
this_module = sys.modules[__name__]
this_classes = set([_o for (_, _o) in inspect.getmembers(this_module) if _isSupersedable(_o) and _o not in raw_classes])
this_classes_tuple = tuple(this_classes)
#print 'This classes: %s' % (this_classes,)
# Raw classes superseded by something in this module
superseded_classes = set([ _o for _o in raw_classes if _o._SupersedingClass() in this_classes ])
superseded_classes_tuple = tuple(superseded_classes)
#print 'Superseded classes: %s' % (superseded_classes,)
# Raw classes that are subclasses of something superseded by this
# module, but that are not themselves superseded by this module
need_supersedure_classes = set([_o for _o in raw_classes if issubclass(_o, superseded_classes_tuple) and _o not in superseded_classes])
#print 'Need supersedure classes: %s' % (need_supersedure_classes,)
# Add local definitions to supersede classes all of whose
# ancestors have been superseded as necessary.
while need_supersedure_classes:
did_replacement = False
new_need_supersedure_classes = set()
for o in need_supersedure_classes:
candidate = True
# Build the new sequence of base classes while we check them.
new_mro = []
for super_o in o.__mro__:
if super_o == o:
# Put the superseded class in its original position (probably first)
new_mro.append(o)
continue
if super_o in need_supersedure_classes:
# Subclass of a class we haven't gotten to yet; put it off
candidate = False
break
# Append the replacement or the original, as needed
if super_o in superseded_classes:
new_mro.append(super_o._SupersedingClass())
else:
new_mro.append(super_o)
if not candidate:
new_need_supersedure_classes.add(o)
continue
# Create a new class that subclasses the replacements
name = o.__name__
new_o = type(name, tuple(new_mro), o.__dict__.copy())
# Install it in the module
setattr(this_module, name, new_o)
# Tell PyXB to use it as the superseding class
o._SetSupersedingClass(new_o)
# Record it so future passes will find it
superseded_classes.add(o)
assert need_supersedure_classes != new_need_supersedure_classes
need_supersedure_classes = new_need_supersedure_classes
_injectClasses()
|