4 # From: Michele Simionato (mis6@pitt.edu)
5 # http://groups.google.com/groups?selm=2259b0e2.0304250413.4be8ee45%40posting.google.com
6 # To solve "TypeError: metatype conflict among bases"
9 def _generatemetaclass(bases, metas):
10 "Internal function called by child"
12 if metas == (type,): # trivial metaclass
13 metabases = (); metaname = "_"
14 else: # non-trivial metaclass
16 metaname = "_"+''.join([m.__name__ for m in metas])
17 trivial = lambda m: m in metabases or m is type
21 if not trivial(meta_b):
22 metabases += (meta_b,)
23 metaname += meta_b.__name__
25 if not metabases: # trivial metabase
27 elif len(metabases) == 1: # single metabase
29 else: # multiple metabases
30 return type(metaname, metabases, {}) # creates a new metaclass
31 #shifting the possible conflict to meta-metaclasses
34 def child(*bases, **options):
35 """Class factory avoiding metatype conflicts: if the base classes have
36 metaclasses conflicting within themselves or with the given metaclass,
37 it automatically generates a compatible metaclass and instantiate the
38 child class from it. The recognized keywords in the option dictionary
39 are name, dic and meta."""
40 name = options.get('name', ''.join([b.__name__ for b in bases])+'_')
41 dic = options.get('dic', {})
42 metas = options.get('metas', (type,))
43 return _generatemetaclass(bases, metas)(name, bases, dic)
60 C = child(A, B, name='C')
63 if __name__ == "__main__":