fork download
  1. from types import prepare_class
  2.  
  3. def combine_meta(name, bases, namespace, **kwargs):
  4. metaclasses = []
  5. for base in bases:
  6. meta, ns, _ = prepare_class(name, (base,), kwargs)
  7. if meta is not type:
  8. if type(ns) is not type(namespace):
  9. if type(namespace) is not dict:
  10. raise TypeError('metaclass conflict: '
  11. 'multiple custom namespaces defined.')
  12. ns.update(namespace)
  13. namespace = ns
  14. elif ns:
  15. namespace.update(ns)
  16. metaclasses = [other for other in metaclasses if not issubclass(meta, other)]
  17. if not any(issubclass(other, meta) for other in metaclasses):
  18. metaclasses.append(meta)
  19. if len(metaclasses) > 1:
  20. meta_name = '_'.join(meta.__name__ for meta in metaclasses)
  21. print(metaclasses)
  22. metaclass = type(meta_name, tuple(metaclasses), {})
  23. else:
  24. metaclass, = metaclasses or (type,)
  25. return metaclass(name, bases, namespace, **kwargs)
  26.  
  27. class M1(type):
  28. pass
  29.  
  30. class M2(M1):
  31. pass
  32.  
  33. class A(metaclass=M1):
  34. pass
  35.  
  36. class B(metaclass=M2):
  37. pass
  38.  
  39. class C(A, B, metaclass=combine_meta):
  40. pass
  41.  
  42. assert type(C) is M2
  43.  
  44. class C(B, A, metaclass=combine_meta):
  45. pass
  46.  
  47. assert type(C) is M2
Success #stdin #stdout 0.03s 9600KB
stdin
Standard input is empty
stdout
Standard output is empty