diff options
Diffstat (limited to 'engine/SCons/Action.py')
-rw-r--r-- | engine/SCons/Action.py | 147 |
1 files changed, 66 insertions, 81 deletions
diff --git a/engine/SCons/Action.py b/engine/SCons/Action.py index 3e766d9..7cad8a5 100644 --- a/engine/SCons/Action.py +++ b/engine/SCons/Action.py @@ -97,13 +97,15 @@ way for wrapping up the functions. # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -__revision__ = "src/engine/SCons/Action.py 4720 2010/03/24 03:14:11 jars" +__revision__ = "src/engine/SCons/Action.py 5023 2010/06/14 22:05:46 scons" + +import SCons.compat -import cPickle import dis import os +# compat layer imports "cPickle" for us if it's available. +import pickle import re -import string import sys import subprocess @@ -117,7 +119,7 @@ import SCons.Subst is_String = SCons.Util.is_String is_List = SCons.Util.is_List -class _null: +class _null(object): pass print_actions = 1 @@ -153,7 +155,7 @@ else: else: result.append(c) i = i+1 - return string.join(result, '') + return ''.join(result) strip_quotes = re.compile('^[\'"](.*)[\'"]$') @@ -208,8 +210,8 @@ def _object_contents(obj): except AttributeError: # Should be a pickable Python object. try: - return cPickle.dumps(obj) - except (cPickle.PicklingError, TypeError): + return pickle.dumps(obj) + except (pickle.PicklingError, TypeError): # This is weird, but it seems that nested classes # are unpickable. The Python docs say it should # always be a PicklingError, but some Python @@ -249,19 +251,19 @@ def _code_contents(code): # Note that we also always ignore the first entry of co_consts # which contains the function doc string. We assume that the # function does not access its doc string. - contents.append(',(' + string.join(map(_object_contents,code.co_consts[1:]),',') + ')') + contents.append(',(' + ','.join(map(_object_contents,code.co_consts[1:])) + ')') # The code contents depends on the variable names used to # accessed global variable, as changing the variable name changes # the variable actually accessed and therefore changes the # function result. - contents.append(',(' + string.join(map(_object_contents,code.co_names),',') + ')') + contents.append(',(' + ','.join(map(_object_contents,code.co_names)) + ')') # The code contents depends on its actual code!!! contents.append(',(' + str(remove_set_lineno_codes(code.co_code)) + ')') - return string.join(contents, '') + return ''.join(contents) def _function_contents(func): @@ -271,7 +273,7 @@ def _function_contents(func): # The function contents depends on the value of defaults arguments if func.func_defaults: - contents.append(',(' + string.join(map(_object_contents,func.func_defaults),',') + ')') + contents.append(',(' + ','.join(map(_object_contents,func.func_defaults)) + ')') else: contents.append(',()') @@ -284,12 +286,12 @@ def _function_contents(func): #xxx = [_object_contents(x.cell_contents) for x in closure] try: - xxx = map(lambda x: _object_contents(x.cell_contents), closure) + xxx = [_object_contents(x.cell_contents) for x in closure] except AttributeError: xxx = [] - contents.append(',(' + string.join(xxx, ',') + ')') + contents.append(',(' + ','.join(xxx) + ')') - return string.join(contents, '') + return ''.join(contents) def _actionAppend(act1, act2): @@ -299,7 +301,7 @@ def _actionAppend(act1, act2): a1 = Action(act1) a2 = Action(act2) if a1 is None or a2 is None: - raise TypeError, "Cannot append %s to %s" % (type(act1), type(act2)) + raise TypeError("Cannot append %s to %s" % (type(act1), type(act2))) if isinstance(a1, ListAction): if isinstance(a2, ListAction): return ListAction(a1.list + a2.list) @@ -353,8 +355,7 @@ def _do_create_action(act, kw): return act if is_List(act): - #TODO(1.5) return CommandAction(act, **kw) - return apply(CommandAction, (act,), kw) + return CommandAction(act, **kw) if callable(act): try: @@ -378,10 +379,9 @@ def _do_create_action(act, kw): # like a function or a CommandGenerator in that variable # instead of a string. return LazyAction(var, kw) - commands = string.split(str(act), '\n') + commands = str(act).split('\n') if len(commands) == 1: - #TODO(1.5) return CommandAction(commands[0], **kw) - return apply(CommandAction, (commands[0],), kw) + return CommandAction(commands[0], **kw) # The list of string commands may include a LazyAction, so we # reprocess them via _do_create_list_action. return _do_create_list_action(commands, kw) @@ -409,7 +409,7 @@ def Action(act, *args, **kw): return _do_create_list_action(act, kw) return _do_create_action(act, kw) -class ActionBase: +class ActionBase(object): """Base class for all types of action objects that can be held by other objects (Builders, Executors, etc.) This provides the common methods for manipulating and combining those actions.""" @@ -434,7 +434,7 @@ class ActionBase: if is_String(vl): vl = (vl,) for v in vl: result.append(env.subst('${'+v+'}')) - return string.join(result, '') + return ''.join(result) def __add__(self, other): return _actionAppend(self, other) @@ -450,7 +450,7 @@ class ActionBase: # and CommandGeneratorAction will use this env # when it calls its _generate method. self.presub_env = env - lines = string.split(str(self), '\n') + lines = str(self).split('\n') self.presub_env = None # don't need this any more return lines @@ -497,7 +497,7 @@ class _ActionAction(ActionBase): SCons.Util.AddMethod(self, batch_key, 'batch_key') def print_cmd_line(self, s, target, source, env): - sys.stdout.write(s + "\n") + sys.stdout.write(s + u"\n") def __call__(self, target, source, env, exitstatfunc=_null, @@ -534,9 +534,9 @@ class _ActionAction(ActionBase): if executor: target = executor.get_all_targets() source = executor.get_all_sources() - t = string.join(map(str, target), ' and ') - l = string.join(self.presub_lines(env), '\n ') - out = "Building %s with action:\n %s\n" % (t, l) + t = ' and '.join(map(str, target)) + l = '\n '.join(self.presub_lines(env)) + out = u"Building %s with action:\n %s\n" % (t, l) sys.stdout.write(out) cmd = None if show and self.strfunction: @@ -590,7 +590,7 @@ def _string_from_cmd_list(cmd_list): if ' ' in arg or '\t' in arg: arg = '"' + arg + '"' cl.append(arg) - return string.join(cl) + return ' '.join(cl) # A fiddlin' little function that has an 'import SCons.Environment' which # can't be moved to the top level without creating an import loop. Since @@ -617,7 +617,7 @@ def get_default_ENV(env): # it in the long run as more and more places use subprocess, but I'm sure # it'll have to be tweaked to get the full desired functionality. # one special arg (so far?), 'error', to tell what to do with exceptions. -def _subproc(env, cmd, error = 'ignore', **kw): +def _subproc(scons_env, cmd, error = 'ignore', **kw): """Do common setup for a subprocess.Popen() call""" # allow std{in,out,err} to be "'devnull'" io = kw.get('stdin') @@ -632,7 +632,7 @@ def _subproc(env, cmd, error = 'ignore', **kw): # Figure out what shell environment to use ENV = kw.get('env', None) - if ENV is None: ENV = get_default_ENV(env) + if ENV is None: ENV = get_default_ENV(scons_env) # Ensure that the ENV values are all strings: new_env = {} @@ -642,7 +642,7 @@ def _subproc(env, cmd, error = 'ignore', **kw): # because that's a pretty common list-like value to stick # in an environment variable: value = SCons.Util.flatten_sequence(value) - new_env[key] = string.join(map(str, value), os.pathsep) + new_env[key] = os.pathsep.join(map(str, value)) else: # It's either a string or something else. If it's a string, # we still want to call str() because it might be a *Unicode* @@ -655,16 +655,16 @@ def _subproc(env, cmd, error = 'ignore', **kw): try: #FUTURE return subprocess.Popen(cmd, **kw) - return apply(subprocess.Popen, (cmd,), kw) + return subprocess.Popen(cmd, **kw) except EnvironmentError, e: if error == 'raise': raise # return a dummy Popen instance that only returns error - class dummyPopen: + class dummyPopen(object): def __init__(self, e): self.exception = e def communicate(self): return ('','') def wait(self): return -self.exception.errno stdin = None - class f: + class f(object): def read(self): return '' def readline(self): return '' stdout = stderr = f() @@ -684,17 +684,16 @@ class CommandAction(_ActionAction): # variables. if __debug__: logInstanceCreation(self, 'Action.CommandAction') - #TODO(1.5) _ActionAction.__init__(self, **kw) - apply(_ActionAction.__init__, (self,), kw) + _ActionAction.__init__(self, **kw) if is_List(cmd): - if filter(is_List, cmd): - raise TypeError, "CommandAction should be given only " \ - "a single command" + if list(filter(is_List, cmd)): + raise TypeError("CommandAction should be given only " \ + "a single command") self.cmd_list = cmd def __str__(self): if is_List(self.cmd_list): - return string.join(map(str, self.cmd_list), ' ') + return ' '.join(map(str, self.cmd_list)) return str(self.cmd_list) def process(self, target, source, env, executor=None): @@ -704,7 +703,7 @@ class CommandAction(_ActionAction): result = env.subst_list(self.cmd_list, 0, target, source) silent = None ignore = None - while 1: + while True: try: c = result[0][0][0] except IndexError: c = None if c == '@': silent = 1 @@ -771,7 +770,7 @@ class CommandAction(_ActionAction): # path list, because that's a pretty common list-like # value to stick in an environment variable: value = flatten_sequence(value) - ENV[key] = string.join(map(str, value), os.pathsep) + ENV[key] = os.pathsep.join(map(str, value)) else: # If it isn't a string or a list, then we just coerce # it to a string, which is the proper way to handle @@ -782,7 +781,7 @@ class CommandAction(_ActionAction): if executor: target = executor.get_all_targets() source = executor.get_all_sources() - cmd_list, ignore, silent = self.process(target, map(rfile, source), env, executor) + cmd_list, ignore, silent = self.process(target, list(map(rfile, source)), env, executor) # Use len() to filter out any "command" that's zero-length. for cmd_line in filter(len, cmd_list): @@ -806,7 +805,7 @@ class CommandAction(_ActionAction): from SCons.Subst import SUBST_SIG cmd = self.cmd_list if is_List(cmd): - cmd = string.join(map(str, cmd)) + cmd = ' '.join(map(str, cmd)) else: cmd = str(cmd) if executor: @@ -859,8 +858,7 @@ class CommandGeneratorAction(ActionBase): source=source, env=env, for_signature=for_signature) - #TODO(1.5) gen_cmd = Action(ret, **self.gen_kw) - gen_cmd = apply(Action, (ret,), self.gen_kw) + gen_cmd = Action(ret, **self.gen_kw) if not gen_cmd: raise SCons.Errors.UserError("Object returned from command generator: %s cannot be used to create an Action." % repr(ret)) return gen_cmd @@ -885,7 +883,9 @@ class CommandGeneratorAction(ActionBase): show=_null, execute=_null, chdir=_null, executor=None): act = self._generate(target, source, env, 0, executor) if act is None: - raise UserError("While building `%s': Cannot deduce file extension from source files: %s" % (repr(map(str, target)), repr(map(str, source)))) + raise UserError("While building `%s': " + "Cannot deduce file extension from source files: %s" + % (repr(list(map(str, target))), repr(list(map(str, source))))) return act(target, source, env, exitstatfunc, presub, show, execute, chdir, executor) @@ -930,7 +930,7 @@ class LazyAction(CommandGeneratorAction, CommandAction): def __init__(self, var, kw): if __debug__: logInstanceCreation(self, 'Action.LazyAction') #FUTURE CommandAction.__init__(self, '${'+var+'}', **kw) - apply(CommandAction.__init__, (self, '${'+var+'}'), kw) + CommandAction.__init__(self, '${'+var+'}', **kw) self.var = SCons.Util.to_String(var) self.gen_kw = kw @@ -945,8 +945,7 @@ class LazyAction(CommandGeneratorAction, CommandAction): c = env.get(self.var, '') else: c = '' - #TODO(1.5) gen_cmd = Action(c, **self.gen_kw) - gen_cmd = apply(Action, (c,), self.gen_kw) + gen_cmd = Action(c, **self.gen_kw) if not gen_cmd: raise SCons.Errors.UserError("$%s value %s cannot be used to create an Action." % (self.var, repr(c))) return gen_cmd @@ -955,10 +954,8 @@ class LazyAction(CommandGeneratorAction, CommandAction): return self._generate_cache(env) def __call__(self, target, source, env, *args, **kw): - args = (self, target, source, env) + args c = self.get_parent_class(env) - #TODO(1.5) return c.__call__(*args, **kw) - return apply(c.__call__, args, kw) + return c.__call__(self, target, source, env, *args, **kw) def get_presig(self, target, source, env): c = self.get_parent_class(env) @@ -986,8 +983,7 @@ class FunctionAction(_ActionAction): # This is weird, just do the best we can. self.funccontents = _object_contents(execfunction) - #TODO(1.5) _ActionAction.__init__(self, **kw) - apply(_ActionAction.__init__, (self,), kw) + _ActionAction.__init__(self, **kw) def function_name(self): try: @@ -1018,7 +1014,7 @@ class FunctionAction(_ActionAction): else: s = str_for_display() return s - return '[' + string.join(map(quote, a), ", ") + ']' + return '[' + ", ".join(map(quote, a)) + ']' try: strfunc = self.execfunction.strfunction except AttributeError: @@ -1045,7 +1041,7 @@ class FunctionAction(_ActionAction): if executor: target = executor.get_all_targets() source = executor.get_all_sources() - rsources = map(rfile, source) + rsources = list(map(rfile, source)) try: result = self.execfunction(target=target, source=rsources, env=env) except KeyboardInterrupt, e: @@ -1095,40 +1091,34 @@ class FunctionAction(_ActionAction): class ListAction(ActionBase): """Class for lists of other actions.""" - def __init__(self, list): + def __init__(self, actionlist): if __debug__: logInstanceCreation(self, 'Action.ListAction') def list_of_actions(x): if isinstance(x, ActionBase): return x return Action(x) - self.list = map(list_of_actions, list) + self.list = list(map(list_of_actions, actionlist)) # our children will have had any varlist # applied; we don't need to do it again self.varlist = () self.targets = '$TARGETS' def genstring(self, target, source, env): - return string.join(map(lambda a, t=target, s=source, e=env: - a.genstring(t, s, e), - self.list), - '\n') + return '\n'.join([a.genstring(target, source, env) for a in self.list]) def __str__(self): - return string.join(map(str, self.list), '\n') + return '\n'.join(map(str, self.list)) def presub_lines(self, env): return SCons.Util.flatten_sequence( - map(lambda a, env=env: a.presub_lines(env), self.list)) + [a.presub_lines(env) for a in self.list]) def get_presig(self, target, source, env): """Return the signature contents of this action list. Simple concatenation of the signatures of the elements. """ - return string.join(map(lambda x, t=target, s=source, e=env: - x.get_contents(t, s, e), - self.list), - "") + return "".join([x.get_contents(target, source, env) for x in self.list]) def __call__(self, target, source, env, exitstatfunc=_null, presub=_null, show=_null, execute=_null, chdir=_null, executor=None): @@ -1153,9 +1143,9 @@ class ListAction(ActionBase): for act in self.list: for var in act.get_varlist(target, source, env, executor): result[var] = True - return result.keys() + return list(result.keys()) -class ActionCaller: +class ActionCaller(object): """A class for delaying calling an Action function with specific (positional and keyword) arguments until the Action is actually executed. @@ -1204,9 +1194,7 @@ class ActionCaller: return self.parent.convert(s) def subst_args(self, target, source, env): - return map(lambda x, self=self, t=target, s=source, e=env: - self.subst(x, t, s, e), - self.args) + return [self.subst(x, target, source, env) for x in self.args] def subst_kw(self, target, source, env): kw = {} @@ -1217,20 +1205,17 @@ class ActionCaller: def __call__(self, target, source, env, executor=None): args = self.subst_args(target, source, env) kw = self.subst_kw(target, source, env) - #TODO(1.5) return self.parent.actfunc(*args, **kw) - return apply(self.parent.actfunc, args, kw) + return self.parent.actfunc(*args, **kw) def strfunction(self, target, source, env): args = self.subst_args(target, source, env) kw = self.subst_kw(target, source, env) - #TODO(1.5) return self.parent.strfunc(*args, **kw) - return apply(self.parent.strfunc, args, kw) + return self.parent.strfunc(*args, **kw) def __str__(self): - #TODO(1.5) return self.parent.strfunc(*self.args, **self.kw) - return apply(self.parent.strfunc, self.args, self.kw) + return self.parent.strfunc(*self.args, **self.kw) -class ActionFactory: +class ActionFactory(object): """A factory class that will wrap up an arbitrary function as an SCons-executable Action object. |