"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "SCons/Action.py" between
SCons-4.3.0.tar.gz and SCons-4.4.0.tar.gz

About: SCons is a software construction tool (a Python script and a set of modules as a superior alternative to the classic "Make" build tool).

Action.py  (SCons-4.3.0):Action.py  (SCons-4.4.0)
skipping to change at line 739 skipping to change at line 739
if not default_ENV: if not default_ENV:
import SCons.Environment import SCons.Environment
# This is a hideously expensive way to get a default shell # This is a hideously expensive way to get a default shell
# environment. What it really should do is run the platform # environment. What it really should do is run the platform
# setup to get the default ENV. Fortunately, it's incredibly # setup to get the default ENV. Fortunately, it's incredibly
# rare for an Environment not to have a shell environment, so # rare for an Environment not to have a shell environment, so
# we're not going to worry about it overmuch. # we're not going to worry about it overmuch.
default_ENV = SCons.Environment.Environment()['ENV'] default_ENV = SCons.Environment.Environment()['ENV']
return default_ENV return default_ENV
def _resolve_shell_env(env, target, source):
"""
First get default environment.
Then if SHELL_ENV_GENERATORS is set and is iterable,
call each callable in that list to allow it to alter
the created execution environment.
"""
ENV = get_default_ENV(env)
shell_gen = env.get('SHELL_ENV_GENERATORS')
if shell_gen:
try:
shell_gens = iter(shell_gen)
except TypeError:
raise SCons.Errors.UserError("SHELL_ENV_GENERATORS must be iteratabl
e.")
else:
ENV = ENV.copy()
for generator in shell_gens:
ENV = generator(env, target, source, ENV)
if not isinstance(ENV, dict):
raise SCons.Errors.UserError(f"SHELL_ENV_GENERATORS function
: {generator} must return a dict.")
return ENV
def _subproc(scons_env, cmd, error='ignore', **kw): def _subproc(scons_env, cmd, error='ignore', **kw):
"""Wrapper for subprocess which pulls from construction env. """Wrapper for subprocess which pulls from construction env.
Use for calls to subprocess which need to interpolate values from Use for calls to subprocess which need to interpolate values from
an SCons construction environment into the environment passed to an SCons construction environment into the environment passed to
subprocess. Adds an an error-handling argument. Adds ability subprocess. Adds an an error-handling argument. Adds ability
to specify std{in,out,err} with "'devnull'" tag. to specify std{in,out,err} with "'devnull'" tag.
""" """
# TODO: just uses subprocess.DEVNULL now, we can drop the "devnull" # TODO: just uses subprocess.DEVNULL now, we can drop the "devnull"
# string now - it is a holdover from Py2, which didn't have DEVNULL. # string now - it is a holdover from Py2, which didn't have DEVNULL.
skipping to change at line 783 skipping to change at line 805
# produce something reasonable for just about everything else: # produce something reasonable for just about everything else:
new_env[key] = str(value) new_env[key] = str(value)
kw['env'] = new_env kw['env'] = new_env
try: try:
pobj = subprocess.Popen(cmd, **kw) pobj = subprocess.Popen(cmd, **kw)
except EnvironmentError as e: except EnvironmentError as e:
if error == 'raise': raise if error == 'raise': raise
# return a dummy Popen instance that only returns error # return a dummy Popen instance that only returns error
class dummyPopen: class dummyPopen:
def __init__(self, e): self.exception = e def __init__(self, e):
def communicate(self, input=None): return ('', '') self.exception = e
def wait(self): return -self.exception.errno # Add the following two to enable using the return value as a contex
t manager
# for example
# with Action._subproc(...) as po:
# logic here which uses po
def __enter__(self):
return self
def __exit__(self, *args):
pass
def communicate(self, input=None):
return ('', '')
def wait(self):
return -self.exception.errno
stdin = None stdin = None
class f: class f:
def read(self): return '' def read(self): return ''
def readline(self): return '' def readline(self): return ''
def __iter__(self): return iter(()) def __iter__(self): return iter(())
stdout = stderr = f() stdout = stderr = f()
pobj = dummyPopen(e) pobj = dummyPopen(e)
finally: finally:
# clean up open file handles stored in parent's kw # clean up open file handles stored in parent's kw
for k, v in kw.items(): for k, v in kw.items():
skipping to change at line 815 skipping to change at line 853
# single item it should be the command string to execute; if a # single item it should be the command string to execute; if a
# list then it should be the words of the command string to # list then it should be the words of the command string to
# execute. Only a single command should be executed by this # execute. Only a single command should be executed by this
# object; lists of commands should be handled by embedding # object; lists of commands should be handled by embedding
# these objects in a ListAction object (which the Action() # these objects in a ListAction object (which the Action()
# factory above does). cmd will be passed to # factory above does). cmd will be passed to
# Environment.subst_list() for substituting environment # Environment.subst_list() for substituting environment
# variables. # variables.
if SCons.Debug.track_instances: logInstanceCreation(self, 'Action.Comman dAction') if SCons.Debug.track_instances: logInstanceCreation(self, 'Action.Comman dAction')
_ActionAction.__init__(self, **kw) super().__init__(**kw)
if is_List(cmd): if is_List(cmd):
if [c for c in cmd if is_List(c)]: if [c for c in cmd if is_List(c)]:
raise TypeError("CommandAction should be given only " raise TypeError("CommandAction should be given only "
"a single command") "a single command")
self.cmd_list = cmd self.cmd_list = cmd
def __str__(self): def __str__(self):
if is_List(self.cmd_list): if is_List(self.cmd_list):
return ' '.join(map(str, self.cmd_list)) return ' '.join(map(str, self.cmd_list))
return str(self.cmd_list) return str(self.cmd_list)
skipping to change at line 891 skipping to change at line 929
try: try:
spawn = env['SPAWN'] spawn = env['SPAWN']
except KeyError: except KeyError:
raise SCons.Errors.UserError('Missing SPAWN construction variable.') raise SCons.Errors.UserError('Missing SPAWN construction variable.')
else: else:
if is_String(spawn): if is_String(spawn):
spawn = env.subst(spawn, raw=1, conv=lambda x: x) spawn = env.subst(spawn, raw=1, conv=lambda x: x)
escape = env.get('ESCAPE', lambda x: x) escape = env.get('ESCAPE', lambda x: x)
ENV = get_default_ENV(env) ENV = _resolve_shell_env(env, target, source)
# Ensure that the ENV values are all strings: # Ensure that the ENV values are all strings:
for key, value in ENV.items(): for key, value in ENV.items():
if not is_String(value): if not is_String(value):
if is_List(value): if is_List(value):
# If the value is a list, then we assume it is a # If the value is a list, then we assume it is a
# path list, because that's a pretty common list-like # path list, because that's a pretty common list-like
# value to stick in an environment variable: # value to stick in an environment variable:
value = flatten_sequence(value) value = flatten_sequence(value)
ENV[key] = os.pathsep.join(map(str, value)) ENV[key] = os.pathsep.join(map(str, value))
skipping to change at line 1195 skipping to change at line 1233
try: try:
self.funccontents = _callable_contents(execfunction) self.funccontents = _callable_contents(execfunction)
except AttributeError: except AttributeError:
try: try:
# See if execfunction will do the heavy lifting for us. # See if execfunction will do the heavy lifting for us.
self.gc = execfunction.get_contents self.gc = execfunction.get_contents
except AttributeError: except AttributeError:
# This is weird, just do the best we can. # This is weird, just do the best we can.
self.funccontents = _object_contents(execfunction) self.funccontents = _object_contents(execfunction)
_ActionAction.__init__(self, **kw) super().__init__(**kw)
def function_name(self): def function_name(self):
try: try:
return self.execfunction.__name__ return self.execfunction.__name__
except AttributeError: except AttributeError:
try: try:
return self.execfunction.__class__.__name__ return self.execfunction.__class__.__name__
except AttributeError: except AttributeError:
return "unknown_python_function" return "unknown_python_function"
 End of changes. 5 change blocks. 
6 lines changed or deleted 47 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)