Skip to content

Commit 04c5b6e

Browse files
authored
Merge pull request SCons#4532 from mwichmann/exception-convert
Improve conversion to BuildError
2 parents 37c7473 + 4b52a1f commit 04c5b6e

File tree

4 files changed

+49
-17
lines changed

4 files changed

+49
-17
lines changed

CHANGES.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,9 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
6363
old Python 2-only code block in a test.
6464
- scons-time tests now supply a "filter" argument to tarfile.extract
6565
to quiet a warning which was added in Python 3.13 beta 1.
66+
- Improved the conversion of a "foreign" exception from an action
67+
into BuildError by making sure our defaults get applied even in
68+
corner cases. Fixes #4530.
6669
- Restructured API docs build (Sphinx) so main module contents appear
6770
on a given page *before* the submodule docs, not after. Also
6871
tweaked the Util package doc build so it's structured more like the

RELEASE.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ FIXES
4949
-----
5050

5151
- OSErrors are now no longer hidden during the execution of Actions.
52+
- Improved the conversion of a "foreign" exception from an action
53+
into BuildError by making sure our defaults get applied even in
54+
corner cases. Fixes Issue #4530
5255

5356
IMPROVEMENTS
5457
------------

SCons/Errors.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,12 @@ def convert_to_BuildError(status, exc_info=None):
177177
# (for example, failure to create the directory in which the
178178
# target file will appear).
179179
filename = getattr(status, 'filename', None)
180-
strerror = getattr(status, 'strerror', str(status))
181-
errno = getattr(status, 'errno', 2)
180+
strerror = getattr(status, 'strerror', None)
181+
if strerror is None:
182+
strerror = str(status)
183+
errno = getattr(status, 'errno', None)
184+
if errno is None:
185+
errno = 2
182186

183187
buildError = BuildError(
184188
errstr=strerror,

SCons/ErrorsTests.py

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def test_BuildError(self):
4646
assert e.command == "c"
4747

4848
try:
49-
raise SCons.Errors.BuildError("n", "foo", 57, 3, "file",
49+
raise SCons.Errors.BuildError("n", "foo", 57, 3, "file",
5050
"e", "a", "c", (1,2,3))
5151
except SCons.Errors.BuildError as e:
5252
assert e.errstr == "foo", e.errstr
@@ -96,26 +96,48 @@ def test_ExplicitExit(self):
9696
assert e.node == "node"
9797

9898
def test_convert_EnvironmentError_to_BuildError(self) -> None:
99-
"""Test the convert_to_BuildError function on SConsEnvironmentError
100-
exceptions.
101-
"""
99+
"""Test convert_to_BuildError on SConsEnvironmentError."""
102100
ee = SCons.Errors.SConsEnvironmentError("test env error")
103101
be = SCons.Errors.convert_to_BuildError(ee)
104-
assert be.errstr == "test env error"
105-
assert be.status == 2
106-
assert be.exitstatus == 2
107-
assert be.filename is None
102+
with self.subTest():
103+
self.assertEqual(be.errstr, "test env error")
104+
with self.subTest():
105+
self.assertEqual(be.status, 2)
106+
with self.subTest():
107+
self.assertEqual(be.exitstatus, 2)
108+
with self.subTest():
109+
self.assertIsNone(be.filename)
108110

109111
def test_convert_OSError_to_BuildError(self) -> None:
110-
"""Test the convert_to_BuildError function on OSError
111-
exceptions.
112-
"""
112+
"""Test convert_to_BuildError on OSError."""
113113
ose = OSError(7, 'test oserror')
114114
be = SCons.Errors.convert_to_BuildError(ose)
115-
assert be.errstr == 'test oserror'
116-
assert be.status == 7
117-
assert be.exitstatus == 2
118-
assert be.filename is None
115+
with self.subTest():
116+
self.assertEqual(be.errstr, 'test oserror')
117+
with self.subTest():
118+
self.assertEqual(be.status, 7)
119+
with self.subTest():
120+
self.assertEqual(be.exitstatus, 2)
121+
with self.subTest():
122+
self.assertIsNone(be.filename)
123+
124+
def test_convert_phony_OSError_to_BuildError(self) -> None:
125+
"""Test convert_to_BuildError on OSError with defaults."""
126+
class PhonyException(OSError):
127+
def __init__(self, name):
128+
OSError.__init__(self, name) # most fields will default to None
129+
self.name = name
130+
131+
ose = PhonyException("test oserror")
132+
be = SCons.Errors.convert_to_BuildError(ose)
133+
with self.subTest():
134+
self.assertEqual(be.errstr, 'test oserror')
135+
with self.subTest():
136+
self.assertEqual(be.status, 2)
137+
with self.subTest():
138+
self.assertEqual(be.exitstatus, 2)
139+
with self.subTest():
140+
self.assertIsNone(be.filename)
119141

120142

121143
if __name__ == "__main__":

0 commit comments

Comments
 (0)