- Fix (?) a runtest.py hang on Windows when the --xml option is used.
+ - Change the message when an error occurs trying to interact with the
+ file system to report the target(s) in square brackets (as before) and
+ the actual file or directory that encountered the error afterwards.
+
From Chen Lee:
- Add x64 support for Microsoft Visual Studio 8.
result = self.execfunction(target=target, source=rsources, env=env)
except EnvironmentError, e:
# If an IOError/OSError happens, raise a BuildError.
- raise SCons.Errors.BuildError(node=target, errstr=e.strerror)
+ # Report the name of the file or directory that caused the
+ # error, which might be different from the target being built
+ # (for example, failure to create the directory in which the
+ # target file will appear).
+ try: filename = e.filename
+ except AttributeError: filename = None
+ raise SCons.Errors.BuildError(node=target,
+ errstr=e.strerror,
+ filename=filename)
return result
def get_contents(self, target, source, env):
class BuildError(Exception):
- def __init__(self, node=None, errstr="Unknown error", *args):
+ def __init__(self, node=None, errstr="Unknown error", filename=None, *args):
self.node = node
self.errstr = errstr
+ self.filename = filename
apply(Exception.__init__, (self,) + args)
class InternalError(Exception):
self.status = status
apply(Exception.__init__, (self,) + args)
+class TaskmasterException(Exception):
+ def __init__(self, node=None, exc_info=(None, None, None), *args):
+ self.node = node
+ self.errstr = "Exception"
+ self.exc_info = exc_info
+ apply(Exception.__init__, (self,) + args)
except SCons.Errors.ExplicitExit, e:
assert e.node == "node"
+ def test_TaskmasterException(self):
+ """Test the TaskmasterException exception."""
+ try:
+ raise SCons.Errors.TaskmasterException("tm exception", (1, 2, 3))
+ except SCons.Errors.TaskmasterException, e:
+ assert e.node == "tm exception"
+ assert e.exc_info == (1, 2, 3)
+
if __name__ == "__main__":
suite = unittest.makeSuite(ErrorsTestCase, 'test_')
if not unittest.TextTestRunner().run(suite).wasSuccessful():
# see if the sys module has one.
t, e = sys.exc_info()[:2]
+ def nodestring(n):
+ if not SCons.Util.is_List(n):
+ n = [ n ]
+ return string.join(map(str, n), ', ')
+
+ errfmt = "scons: *** [%s] %s\n"
+
if t == SCons.Errors.BuildError:
- fname = e.node
- if SCons.Util.is_List(e.node):
- fname = string.join(map(str, e.node), ', ')
- sys.stderr.write("scons: *** [%s] %s\n" % (fname, e.errstr))
- if e.errstr == 'Exception':
- traceback.print_exception(e.args[0], e.args[1], e.args[2])
+ tname = nodestring(e.node)
+ errstr = e.errstr
+ if e.filename:
+ errstr = e.filename + ': ' + errstr
+ sys.stderr.write(errfmt % (tname, errstr))
+ elif t == SCons.Errors.TaskmasterException:
+ tname = nodestring(e.node)
+ sys.stderr.write(errfmt % (tname, e.errstr))
+ type, value, trace = e.exc_info
+ traceback.print_exception(type, value, trace)
elif t == SCons.Errors.ExplicitExit:
status = e.status
- sys.stderr.write("scons: *** [%s] Explicit exit, status %s\n" % (e.node, e.status))
+ tname = nodestring(e.node)
+ errstr = 'Explicit exit, status %s' % status
+ sys.stderr.write(errfmt % (tname, errstr))
else:
if e is None:
e = t
except SCons.Errors.BuildError:
raise
except:
- exc_type, exc_value, exc_traceback = sys.exc_info()
- raise SCons.Errors.BuildError(self.targets[0],
- "Exception",
- exc_type,
- exc_value,
- exc_traceback)
+ raise SCons.Errors.TaskmasterException(self.targets[0],
+ sys.exc_info())
def get_target(self):
"""Fetch the target being built or updated by this task.
t = tm.next_task()
try:
t.execute()
- except SCons.Errors.BuildError, e:
+ except SCons.Errors.TaskmasterException, e:
assert e.node == n4, e.node
assert e.errstr == "Exception", e.errstr
- assert len(e.args) == 3, `e.args`
- assert e.args[0] == OtherError, e.args[0]
- assert isinstance(e.args[1], OtherError), type(e.args[1])
+ assert len(e.exc_info) == 3, e.exc_info
exc_traceback = sys.exc_info()[2]
- assert type(e.args[2]) == type(exc_traceback), e.args[2]
+ assert type(e.exc_info[2]) == type(exc_traceback), e.exc_info[2]
else:
raise TestFailed, "did not catch expected BuildError"
os.chmod(test.workpath('work', 'export'), 0555)
f = open(f1_out, 'rb')
+expect = """\
+scons: *** [%s] %s: Permission denied
+""" % (os.path.join('export', 'f1.out'),
+ test.workpath('work', 'export', 'f1.out'))
+
test.run(chdir = 'work',
arguments = f1_out,
- stderr="scons: *** [%s] Permission denied\n" % os.path.join('export', 'f1.out'),
+ stderr=expect,
status=2)
f.close()
test.description_set("Incorrect STDERR:\n%s" % test.stderr())
errs = [
- "scons: *** [test2.out] Permission denied\n",
- "scons: *** [test2.out] permission denied\n",
+ "scons: *** [test2.out] test2.out: Permission denied\n",
+ "scons: *** [test2.out] test2.out: permission denied\n",
]
test.fail_test(test.stderr() not in errs)