summaryrefslogtreecommitdiff
path: root/engine/SCons/Taskmaster.py
diff options
context:
space:
mode:
Diffstat (limited to 'engine/SCons/Taskmaster.py')
-rw-r--r--engine/SCons/Taskmaster.py79
1 files changed, 32 insertions, 47 deletions
diff --git a/engine/SCons/Taskmaster.py b/engine/SCons/Taskmaster.py
index ec81af2..68ac1f5 100644
--- a/engine/SCons/Taskmaster.py
+++ b/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