1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 """
18 The I{depsolve} module defines a class for performing dependancy solving.
19 """
20
21 from logging import getLogger
22 from suds import *
23
24 log = getLogger(__name__)
25
26
28 """
29 Dependancy solving list.
30 Items are tuples: (object, (deps,))
31 @ivar raw: The raw (unsorted) items.
32 @type raw: list
33 @ivar index: The index of (unsorted) items.
34 @type index: list
35 @ivar stack: The sorting stack.
36 @type stack: list
37 @ivar pushed: The I{pushed} set tracks items that have been
38 processed.
39 @type pushed: set
40 @ivar sorted: The sorted list of items.
41 @type sorted: list
42 """
43
45 """ """
46 self.unsorted = []
47 self.index = {}
48 self.stack = []
49 self.pushed = set()
50 self.sorted = None
51
52 - def add(self, *items):
53 """
54 Add items to be sorted.
55 @param items: One or more items to be added.
56 @type items: I{item}
57 @return: self
58 @rtype: L{DepList}
59 """
60 for item in items:
61 self.unsorted.append(item)
62 key = item[0]
63 self.index[key] = item
64 return self
65
67 """
68 Sort the list based on dependancies.
69 @return: The sorted items.
70 @rtype: list
71 """
72 self.sorted = list()
73 self.pushed = set()
74 for item in self.unsorted:
75 popped = []
76 self.push(item)
77 while len(self.stack):
78 try:
79 top = self.top()
80 ref = top[1].next()
81 refd = self.index.get(ref)
82 if refd is None:
83 log.debug('"%s" not found, skipped', Repr(ref))
84 continue
85 self.push(refd)
86 except StopIteration:
87 popped.append(self.pop())
88 continue
89 for p in popped:
90 self.sorted.append(p)
91 self.unsorted = self.sorted
92 return self.sorted
93
95 """
96 Get the item at the top of the stack.
97 @return: The top item.
98 @rtype: (item, iter)
99 """
100 return self.stack[-1]
101
102 - def push(self, item):
103 """
104 Push and item onto the sorting stack.
105 @param item: An item to push.
106 @type item: I{item}
107 @return: The number of items pushed.
108 @rtype: int
109 """
110 if item in self.pushed:
111 return
112 frame = (item, iter(item[1]))
113 self.stack.append(frame)
114 self.pushed.add(item)
115
117 """
118 Pop the top item off the stack and append
119 it to the sorted list.
120 @return: The popped item.
121 @rtype: I{item}
122 """
123 try:
124 frame = self.stack.pop()
125 return frame[0]
126 except:
127 pass
128
129
130 if __name__ == '__main__':
131 a = ('a', ('x',))
132 b = ('b', ('a',))
133 c = ('c', ('a','b'))
134 d = ('d', ('c',))
135 e = ('e', ('d','a'))
136 f = ('f', ('e','c','d','a'))
137 x = ('x', ())
138 L = DepList()
139 L.add(c, e, d, b, f, a, x)
140 print [x[0] for x in L.sort()]
141