/usr/lib/python2.7/dist-packages/cylc/c3mro.py is in python-cylc 7.6.0-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | #!/usr/bin/env python
from copy import copy
"""
The C3 algorithm is used to linearize multiple inheritance hierarchies
in Python and other languages (MRO = Method Resolution Order). The code
in this doc string is by Samuele Pedroni and Michele Simionato and taken
from the official Python web site, here:
http://www.python.org/download/releases/2.3/mro/
For cylc, to linearize the runtime inheritance hierarchy, merge()
is unchanged - it works on generic sequences - but mro() had to be
modified to work with lists of names instead of Python base classes.
class __metaclass__(type):
"All classes are metamagically modified to be nicely printed"
__repr__ = lambda cls: cls.__name__
class ex_2:
"Serious order disagreement" #From Guido
class O: pass
class X(O): pass
class Y(O): pass
class A(X,Y): pass
class B(Y,X): pass
try:
class Z(A,B): pass #creates Z(A,B) in Python 2.2
except TypeError:
pass # Z(A,B) cannot be created in Python 2.3
class ex_5:
"My first example"
class O: pass
class F(O): pass
class E(O): pass
class D(O): pass
class C(D,F): pass
class B(D,E): pass
class A(B,C): pass
class ex_6:
"My second example"
class O: pass
class F(O): pass
class E(O): pass
class D(O): pass
class C(D,F): pass
class B(E,D): pass
class A(B,C): pass
class ex_9:
"Difference between Python 2.2 MRO and C3" #From Samuele
class O: pass
class A(O): pass
class B(O): pass
class C(O): pass
class D(O): pass
class E(O): pass
class K1(A,B,C): pass
class K2(D,B,E): pass
class K3(D,A): pass
class Z(K1,K2,K3): pass
def merge(seqs):
print '\n\nCPL[%s]=%s' % (seqs[0][0],seqs),
res = []; i=0
while 1:
nonemptyseqs=[seq for seq in seqs if seq]
if not nonemptyseqs: return res
i+=1; print '\n',i,'round: candidates...',
for seq in nonemptyseqs: # find merge candidates among seq heads
cand = seq[0]; print ' ',cand,
nothead=[s for s in nonemptyseqs if cand in s[1:]]
if nothead: cand=None #reject candidate
else: break
if not cand: raise "Inconsistent hierarchy"
res.append(cand)
for seq in nonemptyseqs: # remove cand
if seq[0] == cand: del seq[0]
def mro(C):
"Compute the class precedence list (mro) according to C3"
return merge([[C]]+map(mro,C.__bases__)+[list(C.__bases__)])
def print_mro(C):
print '\nMRO[%s]=%s' % (C,mro(C))
print '\nP22 MRO[%s]=%s' % (C,C.mro())
print_mro(ex_9.Z)
"""
class C3(object):
def __init__(self, tree={}):
self.tree = tree
def merge(self, seqs):
# print '\n\nCPL[%s]=%s' % (seqs[0][0],seqs),
res = []
i = 0
while 1:
nonemptyseqs = [seq for seq in seqs if seq]
if not nonemptyseqs:
return res
i += 1 # print '\n',i,'round: candidates...',
for seq in nonemptyseqs: # find merge candidates among seq heads
cand = seq[0] # print ' ',cand,
nothead = [s for s in nonemptyseqs if cand in s[1:]]
if nothead:
cand = None # reject candidate
else:
break
if not cand:
raise Exception(
"ERROR: bad runtime namespace inheritance hierarchy.\n"
"See the cylc documentation on multiple inheritance.")
res.append(cand)
for seq in nonemptyseqs: # remove cand
if seq[0] == cand:
del seq[0]
def mro(self, C):
"""Compute the precedence list (mro) according to C3"""
# copy() required here for tree to remain unchanged
return self.merge(
[[C]] + map(self.mro, self.tree[C]) + [copy(self.tree[C])])
if __name__ == "__main__":
parents = {}
parents['root'] = []
parents['a'] = ['root']
parents['b'] = ['root']
parents['foo'] = ['a', 'b']
print 'foo', C3(parents).mro('foo')
parents = {}
parents['o'] = []
parents['a'] = ['o']
parents['b'] = ['o']
parents['c'] = ['o']
parents['d'] = ['o']
parents['e'] = ['o']
parents['k1'] = ['a', 'b', 'c']
parents['k2'] = ['d', 'b', 'e']
parents['k3'] = ['d', 'a']
parents['z'] = ['k1', 'k2', 'k3']
print 'z', C3(parents).mro('z')
# Note we can get Python's result by defining an equivalent class
# hierarchy (with empty class bodies) and printing foo.__mro__.
|