diff options
Diffstat (limited to 'src/engine/SCons/Taskmaster.py')
-rw-r--r-- | src/engine/SCons/Taskmaster.py | 79 |
1 files changed, 32 insertions, 47 deletions
diff --git a/src/engine/SCons/Taskmaster.py b/src/engine/SCons/Taskmaster.py index ec81af2..68ac1f5 100644 --- a/src/engine/SCons/Taskmaster.py +++ b/src/engine/SCons/Taskmaster.py @@ -19,7 +19,6 @@ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -# __doc__ = """ Generic Taskmaster module for the SCons build engine. @@ -48,11 +47,10 @@ interface and the SCons build engine. There are two key classes here: target(s) that it decides need to be evaluated and/or built. """ -__revision__ = "src/engine/SCons/Taskmaster.py 4720 2010/03/24 03:14:11 jars" +__revision__ = "src/engine/SCons/Taskmaster.py 5023 2010/06/14 22:05:46 scons" from itertools import chain import operator -import string import sys import traceback @@ -75,7 +73,7 @@ NODE_FAILED = SCons.Node.failed CollectStats = None -class Stats: +class Stats(object): """ A simple class for holding statistics about the disposition of a Node by the Taskmaster. If we're collecting statistics, each Node @@ -107,13 +105,12 @@ fmt = "%(considered)3d "\ "%(build)3d " def dump_stats(): - StatsNodes.sort(lambda a, b: cmp(str(a), str(b))) - for n in StatsNodes: + for n in sorted(StatsNodes, key=lambda a: str(a)): print (fmt % n.stats.__dict__) + str(n) -class Task: +class Task(object): """ Default SCons build engine task. @@ -165,7 +162,7 @@ class Task: the Action is actually called to build the targets. """ T = self.tm.trace - if T: T.write(self.trace_message('Task.prepare()', self.node)) + if T: T.write(self.trace_message(u'Task.prepare()', self.node)) # Now that it's the appropriate time, give the TaskMaster a # chance to raise any exceptions it encountered while preparing @@ -204,8 +201,9 @@ class Task: # Deprecation Cycle) so the desired behavior is explicitly # determined by which concrete subclass is used. #raise NotImplementedError - msg = ('Direct use of the Taskmaster.Task class will be deprecated\n' - + '\tin a future release.') + msg = ('Taskmaster.Task is an abstract base class; instead of\n' + '\tusing it directly, ' + 'derive from it and override the abstract methods.') SCons.Warnings.warn(SCons.Warnings.TaskmasterNeedsExecuteWarning, msg) return True @@ -218,7 +216,7 @@ class Task: prepare(), executed() or failed(). """ T = self.tm.trace - if T: T.write(self.trace_message('Task.execute()', self.node)) + if T: T.write(self.trace_message(u'Task.execute()', self.node)) try: everything_was_cached = 1 @@ -370,7 +368,7 @@ class Task: This is the default behavior for building only what's necessary. """ T = self.tm.trace - if T: T.write(self.trace_message('Task.make_ready_current()', + if T: T.write(self.trace_message(u'Task.make_ready_current()', self.node)) self.out_of_date = [] @@ -415,7 +413,7 @@ class Task: that can be put back on the candidates list. """ T = self.tm.trace - if T: T.write(self.trace_message('Task.postprocess()', self.node)) + if T: T.write(self.trace_message(u'Task.postprocess()', self.node)) # We may have built multiple targets, some of which may have # common parents waiting for this build. Count up how many @@ -432,7 +430,7 @@ class Task: # A node can only be in the pending_children set if it has # some waiting_parents. if t.waiting_parents: - if T: T.write(self.trace_message('Task.postprocess()', + if T: T.write(self.trace_message(u'Task.postprocess()', t, 'removing')) pending_children.discard(t) @@ -451,7 +449,7 @@ class Task: for p, subtract in parents.items(): p.ref_count = p.ref_count - subtract - if T: T.write(self.trace_message('Task.postprocess()', + if T: T.write(self.trace_message(u'Task.postprocess()', p, 'adjusted parent ref count')) if p.ref_count == 0: @@ -552,7 +550,7 @@ def find_cycle(stack, visited): return None -class Taskmaster: +class Taskmaster(object): """ The Taskmaster for walking the dependency DAG. """ @@ -735,12 +733,12 @@ class Taskmaster: self.ready_exc = None T = self.trace - if T: T.write('\n' + self.trace_message('Looking for a node to evaluate')) + if T: T.write(u'\n' + self.trace_message('Looking for a node to evaluate')) - while 1: + while True: node = self.next_candidate() if node is None: - if T: T.write(self.trace_message('No candidate anymore.') + '\n') + if T: T.write(self.trace_message('No candidate anymore.') + u'\n') return None node = node.disambiguate() @@ -763,7 +761,7 @@ class Taskmaster: else: S = None - if T: T.write(self.trace_message(' Considering node %s and its children:' % self.trace_node(node))) + if T: T.write(self.trace_message(u' Considering node %s and its children:' % self.trace_node(node))) if state == NODE_NO_STATE: # Mark this node as being on the execution stack: @@ -771,7 +769,7 @@ class Taskmaster: elif state > NODE_PENDING: # Skip this node if it has already been evaluated: if S: S.already_handled = S.already_handled + 1 - if T: T.write(self.trace_message(' already handled (executed)')) + if T: T.write(self.trace_message(u' already handled (executed)')) continue executor = node.get_executor() @@ -802,7 +800,7 @@ class Taskmaster: for child in chain(executor.get_all_prerequisites(), children): childstate = child.get_state() - if T: T.write(self.trace_message(' ' + self.trace_node(child))) + if T: T.write(self.trace_message(u' ' + self.trace_node(child))) if childstate == NODE_NO_STATE: children_not_visited.append(child) @@ -861,7 +859,7 @@ class Taskmaster: # count so we can be put back on the list for # re-evaluation when they've all finished. node.ref_count = node.ref_count + child.add_to_waiting_parents(node) - if T: T.write(self.trace_message(' adjusted ref count: %s, child %s' % + if T: T.write(self.trace_message(u' adjusted ref count: %s, child %s' % (self.trace_node(node), repr(str(child))))) if T: @@ -887,7 +885,7 @@ class Taskmaster: # The default when we've gotten through all of the checks above: # this node is ready to be built. if S: S.build = S.build + 1 - if T: T.write(self.trace_message('Evaluating %s\n' % + if T: T.write(self.trace_message(u'Evaluating %s\n' % self.trace_node(node))) # For debugging only: @@ -952,17 +950,8 @@ class Taskmaster: T.write(self.trace_message(' removing node %s from the pending children set\n' % self.trace_node(n))) try: - while 1: - try: - node = to_visit.pop() - except AttributeError: - # Python 1.5.2 - if len(to_visit): - node = to_visit[0] - to_visit.remove(node) - else: - break - + while len(to_visit): + node = to_visit.pop() node_func(node) # Prune recursion by flushing the waiting children @@ -982,7 +971,7 @@ class Taskmaster: pass # We have the stick back the pending_children list into the - # task master because the python 1.5.2 compatibility does not + # taskmaster because the python 1.5.2 compatibility does not # allow us to use in-place updates self.pending_children = pending_children @@ -999,16 +988,12 @@ class Taskmaster: if not self.pending_children: return - # TODO(1.5) - #nclist = [ (n, find_cycle([n], set())) for n in self.pending_children ] - nclist = map(lambda n: (n, find_cycle([n], set())), self.pending_children) + nclist = [(n, find_cycle([n], set())) for n in self.pending_children] - # TODO(1.5) - #genuine_cycles = [ - # node for node, cycle in nclist - # if cycle or node.get_state() != NODE_EXECUTED - #] - genuine_cycles = filter(lambda t: t[1] or t[0].get_state() != NODE_EXECUTED, nclist) + genuine_cycles = [ + node for node,cycle in nclist + if cycle or node.get_state() != NODE_EXECUTED + ] if not genuine_cycles: # All of the "cycles" found were single nodes in EXECUTED state, # which is to say, they really weren't cycles. Just return. @@ -1017,13 +1002,13 @@ class Taskmaster: desc = 'Found dependency cycle(s):\n' for node, cycle in nclist: if cycle: - desc = desc + " " + string.join(map(str, cycle), " -> ") + "\n" + desc = desc + " " + " -> ".join(map(str, cycle)) + "\n" else: desc = desc + \ " Internal Error: no cycle found for node %s (%s) in state %s\n" % \ (node, repr(node), StateString[node.get_state()]) - raise SCons.Errors.UserError, desc + raise SCons.Errors.UserError(desc) # Local Variables: # tab-width:4 |