Skip to content

Commit

Permalink
Modernize stat usage
Browse files Browse the repository at this point in the history
Since Python 2.2, the object returned by an os.stat() call presents
attributes matching the 10-tuple of stat values. Use these instead of
indexing into the tuple.

As usual for non-removed tests, minor tweaks made if needed -
copyright header and DefautlEnvironment() call for performance.

Signed-off-by: Mats Wichmann <[email protected]>
  • Loading branch information
mwichmann committed Dec 15, 2024
1 parent 8e216da commit 9d5e76a
Show file tree
Hide file tree
Showing 24 changed files with 123 additions and 116 deletions.
2 changes: 2 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER
Only object-like macros are replaced (not function-like), and
only on a whole-word basis; recursion is limited to five levels
and does not error out if that limit is reached (issue #4523).
- Minor modernization: make use of stat object's st_mode, st_mtime
and other attributes rather than indexing into stat return.


RELEASE 4.8.1 - Tue, 03 Sep 2024 17:22:20 -0700
Expand Down
4 changes: 4 additions & 0 deletions RELEASE.txt
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ FIXES
only on a whole-word basis; recursion is limited to five levels
and does not error out if that limit is reached (issue #4523).

- Minor modernization: make use of stat object's st_mode, st_mtime
and other attributes rather than indexing into stat return.


IMPROVEMENTS
------------

Expand Down
2 changes: 1 addition & 1 deletion SCons/CacheDir.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ def CacheRetrieveFunc(target, source, env) -> int:
except OSError:
pass
st = fs.stat(cachefile)
fs.chmod(t.get_internal_path(), stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
fs.chmod(t.get_internal_path(), stat.S_IMODE(st.st_mode) | stat.S_IWRITE)
return 0

def CacheRetrieveString(target, source, env) -> str:
Expand Down
2 changes: 1 addition & 1 deletion SCons/Node/FS.py
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,7 @@ def getmtime(self):
st = self.stat()

if st:
return st[stat.ST_MTIME]
return st.st_mtime
else:
return None

Expand Down
4 changes: 2 additions & 2 deletions SCons/Node/FSTests.py
Original file line number Diff line number Diff line change
Expand Up @@ -774,7 +774,7 @@ def test_update(self) -> None:

ni.update(fff)

mtime = st[stat.ST_MTIME]
mtime = st.st_mtime
assert ni.timestamp == mtime, (ni.timestamp, mtime)
size = st.st_size
assert ni.size == size, (ni.size, size)
Expand All @@ -786,7 +786,7 @@ def test_update(self) -> None:

st = os.stat('fff')

mtime = st[stat.ST_MTIME]
mtime = st.st_mtime
assert ni.timestamp != mtime, (ni.timestamp, mtime)
size = st.st_size
assert ni.size != size, (ni.size, size)
Expand Down
4 changes: 2 additions & 2 deletions SCons/Tool/install.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ def copyFunc(dest, source, env) -> int:
else:
copy2(source, dest)
st = os.stat(source)
os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
os.chmod(dest, stat.S_IMODE(st.st_mode) | stat.S_IWRITE)

return 0

Expand Down Expand Up @@ -204,7 +204,7 @@ def copyFuncVersionedLib(dest, source, env) -> int:
pass
copy2(source, dest)
st = os.stat(source)
os.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE)
os.chmod(dest, stat.S_IMODE(st.st_mode) | stat.S_IWRITE)
installShlibLinks(dest, source, env)

return 0
Expand Down
2 changes: 1 addition & 1 deletion site_scons/Utilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def whereis(filename):
st = os.stat(f_ext)
except:
continue
if stat.S_IMODE(st[stat.ST_MODE]) & 0o111:
if stat.S_IMODE(st.st_mode) & stat.S_IXUSR:
return f_ext
return None

Expand Down
2 changes: 1 addition & 1 deletion test/Actions/append.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def after(env, target, source):

test.run(arguments='.')
test.must_match('before.txt', 'Bar\n')
os.chmod(after_exe, os.stat(after_exe)[stat.ST_MODE] | stat.S_IXUSR)
os.chmod(after_exe, os.stat(after_exe).st_mode | stat.S_IXUSR)
test.run(program=after_exe, stdout="Foo\n")
test.pass_test()

Expand Down
4 changes: 2 additions & 2 deletions test/Actions/pre-post.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def before(env, target, source):
a=str(target[0])
with open(a, "wb") as f:
f.write(b"Foo\\n")
os.chmod(a, os.stat(a)[stat.ST_MODE] | stat.S_IXUSR)
os.chmod(a, os.stat(a).st_mode | stat.S_IXUSR)
with open("before.txt", "ab") as f:
f.write((os.path.splitext(str(target[0]))[0] + "\\n").encode())
Expand All @@ -59,7 +59,7 @@ def after(env, target, source):
a = "after_" + t
with open(t, "rb") as fin, open(a, "wb") as fout:
fout.write(fin.read())
os.chmod(a, os.stat(a)[stat.ST_MODE] | stat.S_IXUSR)
os.chmod(a, os.stat(a).st_mode | stat.S_IXUSR)
foo = env.Program(source='foo.c', target='foo')
AddPreAction(foo, before)
Expand Down
77 changes: 39 additions & 38 deletions test/Chmod.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def cat(env, source, target):
f.write(infp.read())
Cat = Action(cat)
DefaultEnvironment(tools=[]) # test speedup
env = Environment()
env.Command(
'bar.out',
Expand Down Expand Up @@ -154,92 +155,92 @@ def cat(env, source, target):
""")
test.run(options = '-n', arguments = '.', stdout = expect)

s = stat.S_IMODE(os.stat(test.workpath('f1'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f1')).st_mode)
test.fail_test(s != 0o444)
s = stat.S_IMODE(os.stat(test.workpath('f1-File'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f1-File')).st_mode)
test.fail_test(s != 0o444)
s = stat.S_IMODE(os.stat(test.workpath('d2'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('d2')).st_mode)
test.fail_test(s != 0o555)
s = stat.S_IMODE(os.stat(test.workpath('d2-Dir'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('d2-Dir')).st_mode)
test.fail_test(s != 0o555)
test.must_not_exist('bar.out')
s = stat.S_IMODE(os.stat(test.workpath('f3'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f3')).st_mode)
test.fail_test(s != 0o444)
s = stat.S_IMODE(os.stat(test.workpath('d4'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('d4')).st_mode)
test.fail_test(s != 0o555)
s = stat.S_IMODE(os.stat(test.workpath('f5'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f5')).st_mode)
test.fail_test(s != 0o444)
test.must_not_exist('f6.out')
test.must_not_exist('f7.out')
s = stat.S_IMODE(os.stat(test.workpath('Chmod-f7.in'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('Chmod-f7.in')).st_mode)
test.fail_test(s != 0o444)
s = stat.S_IMODE(os.stat(test.workpath('f7.out-Chmod'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f7.out-Chmod')).st_mode)
test.fail_test(s != 0o444)
test.must_not_exist('f8.out')
s = stat.S_IMODE(os.stat(test.workpath('f9'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f9')).st_mode)
test.fail_test(s != 0o444)
s = stat.S_IMODE(os.stat(test.workpath('f10'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f10')).st_mode)
test.fail_test(s != 0o444)
s = stat.S_IMODE(os.stat(test.workpath('d11'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('d11')).st_mode)
test.fail_test(s != 0o555)
s = stat.S_IMODE(os.stat(test.workpath('d12'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('d12')).st_mode)
test.fail_test(s != 0o555)
s = stat.S_IMODE(os.stat(test.workpath('f13'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f13')).st_mode)
test.fail_test(s != 0o444)
s = stat.S_IMODE(os.stat(test.workpath('f14'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f14')).st_mode)
test.fail_test(s != 0o444)
s = stat.S_IMODE(os.stat(test.workpath('f15'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f15')).st_mode)
test.fail_test(s != 0o444)
s = stat.S_IMODE(os.stat(test.workpath('d16'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('d16')).st_mode)
test.fail_test(s != 0o555)
s = stat.S_IMODE(os.stat(test.workpath('d17'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('d17')).st_mode)
test.fail_test(s != 0o555)
s = stat.S_IMODE(os.stat(test.workpath('d18'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('d18')).st_mode)
test.fail_test(s != 0o555)

test.run()

s = stat.S_IMODE(os.stat(test.workpath('f1'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f1')).st_mode)
test.fail_test(s != 0o666)
s = stat.S_IMODE(os.stat(test.workpath('f1-File'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f1-File')).st_mode)
test.fail_test(s != 0o666)
s = stat.S_IMODE(os.stat(test.workpath('d2'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('d2')).st_mode)
test.fail_test(s != 0o777)
s = stat.S_IMODE(os.stat(test.workpath('d2-Dir'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('d2-Dir')).st_mode)
test.fail_test(s != 0o777)
test.must_match('bar.out', "bar.in\n")
s = stat.S_IMODE(os.stat(test.workpath('f3'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f3')).st_mode)
test.fail_test(s != 0o666)
s = stat.S_IMODE(os.stat(test.workpath('d4'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('d4')).st_mode)
test.fail_test(s != 0o777)
s = stat.S_IMODE(os.stat(test.workpath('f5'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f5')).st_mode)
test.fail_test(s != 0o666)
test.must_match('f6.out', "f6.in\n")
test.must_match('f7.out', "f7.in\n")
s = stat.S_IMODE(os.stat(test.workpath('Chmod-f7.in'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('Chmod-f7.in')).st_mode)
test.fail_test(s != 0o666)
s = stat.S_IMODE(os.stat(test.workpath('f7.out-Chmod'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f7.out-Chmod')).st_mode)
test.fail_test(s != 0o666)
test.must_match('f8.out', "f8.in\n")
s = stat.S_IMODE(os.stat(test.workpath('f9'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f9')).st_mode)
test.fail_test(s != 0o666)
s = stat.S_IMODE(os.stat(test.workpath('f10'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f10')).st_mode)
test.fail_test(s != 0o666)
s = stat.S_IMODE(os.stat(test.workpath('d11'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('d11')).st_mode)
test.fail_test(s != 0o777)
s = stat.S_IMODE(os.stat(test.workpath('d12'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('d12')).st_mode)
test.fail_test(s != 0o777)
s = stat.S_IMODE(os.stat(test.workpath('f13'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f13')).st_mode)
test.fail_test(s != 0o444)
s = stat.S_IMODE(os.stat(test.workpath('f14'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f14')).st_mode)
test.fail_test(s != 0o666)
s = stat.S_IMODE(os.stat(test.workpath('f15'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('f15')).st_mode)
test.fail_test(s != 0o666)
s = stat.S_IMODE(os.stat(test.workpath('d16'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('d16')).st_mode)
test.fail_test(s != 0o777)
s = stat.S_IMODE(os.stat(test.workpath('d17'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('d17')).st_mode)
test.fail_test(s != 0o777)
s = stat.S_IMODE(os.stat(test.workpath('d18'))[stat.ST_MODE])
s = stat.S_IMODE(os.stat(test.workpath('d18')).st_mode)
test.fail_test(s != 0o777)

test.pass_test()
Expand Down
2 changes: 1 addition & 1 deletion test/Decider/MD5-timestamp-Repository.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
test.sleep() # delay for timestamps
test.write(['Repository','content1.in'], "content1.in 2\n")
test.touch(['Repository','content2.in'])
time_content = os.stat(os.path.join(repository,'content3.in'))[stat.ST_MTIME]
time_content = os.stat(os.path.join(repository,'content3.in')).st_mtime
test.write(['Repository','content3.in'], "content3.in 2\n")
test.touch(['Repository','content3.in'], time_content)

Expand Down
2 changes: 1 addition & 1 deletion test/Decider/MD5-timestamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
test.write('content1.in', "content1.in 2\n")
test.touch('content2.in')

time_content = os.stat('content3.in')[stat.ST_MTIME]
time_content = os.stat('content3.in').st_mtime
test.write('content3.in', "content3.in 2\n")
test.touch('content3.in', time_content)

Expand Down
4 changes: 2 additions & 2 deletions test/Decider/timestamp.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,8 @@
test.run(arguments = '.')
test.up_to_date(arguments = '.')

time_match = os.stat('match2.out')[stat.ST_MTIME]
time_newer = os.stat('newer2.out')[stat.ST_MTIME]
time_match = os.stat('match2.out').st_mtime
time_newer = os.stat('newer2.out').st_mtime

# Now make all the source files newer than (different timestamps from)
# the last time the targets were built, and touch the target files
Expand Down
6 changes: 3 additions & 3 deletions test/Removed/BuildDir/Old/BuildDir.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,16 +224,16 @@ def filter_tempnam(err):
def equal_stats(x,y):
x = os.stat(x)
y = os.stat(y)
return (stat.S_IMODE(x[stat.ST_MODE]) == stat.S_IMODE(y[stat.ST_MODE]) and
x[stat.ST_MTIME] == y[stat.ST_MTIME])
return (stat.S_IMODE(x.st_mode) == stat.S_IMODE(y.st_mode) and
x.st_mtime == y.st_mtime)

# Make sure we did duplicate the source files in build/var2,
# and that their stats are the same:
test.must_exist(['work1', 'build', 'var2', 'f1.c'])
test.must_exist(['work1', 'build', 'var2', 'f2.in'])
test.fail_test(not equal_stats(test.workpath('work1', 'build', 'var2', 'f1.c'), test.workpath('work1', 'src', 'f1.c')))
test.fail_test(not equal_stats(test.workpath('work1', 'build', 'var2', 'f2.in'), test.workpath('work1', 'src', 'f2.in')))

# Make sure we didn't duplicate the source files in build/var3.
test.must_not_exist(['work1', 'build', 'var3', 'f1.c'])
test.must_not_exist(['work1', 'build', 'var3', 'f2.in'])
Expand Down
22 changes: 11 additions & 11 deletions test/Removed/BuildDir/Old/SConscript-build_dir.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/usr/bin/env python
#
# __COPYRIGHT__
# MIT License
#
# Copyright The SCons Foundation
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
Expand All @@ -20,9 +22,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.
#

__revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__"

"""
Verify that specifying a build_dir argument to SConscript still works.
Expand Down Expand Up @@ -108,7 +107,7 @@ def cat(env, source, target):
# VariantDir('build/var9', '.')
# SConscript('build/var9/src/SConscript')
SConscript('src/SConscript', build_dir='build/var9', src_dir='.')
""")
""")

test.subdir(['test', 'src'], ['test', 'alt'])

Expand Down Expand Up @@ -152,8 +151,8 @@ def cat(env, source, target):
def equal_stats(x,y):
x = os.stat(x)
y = os.stat(y)
return (stat.S_IMODE(x[stat.ST_MODE]) == stat.S_IMODE(y[stat.ST_MODE]) and
x[stat.ST_MTIME] == y[stat.ST_MTIME])
return (stat.S_IMODE(x.st_mode) == stat.S_IMODE(y.st_mode) and
x.st_mtime == y.st_mtime)

# Make sure we did duplicate the source files in build/var1,
# and that their stats are the same:
Expand All @@ -168,12 +167,12 @@ def equal_stats(x,y):
test.must_exist(test.workpath('test', 'build', 'var2', file))
test.fail_test(not equal_stats(test.workpath('test', 'build', 'var2', file),
test.workpath('test', 'src', file)))

# Make sure we didn't duplicate the source files in build/var3.
test.must_not_exist(test.workpath('test', 'build', 'var3', 'aaa.in'))
test.must_not_exist(test.workpath('test', 'build', 'var3', 'bbb.in'))
test.must_not_exist(test.workpath('test', 'build', 'var3', 'ccc.in'))

#XXX We can't support var4 and var5 yet, because our VariantDir linkage
#XXX is to an entire source directory. We haven't yet generalized our
#XXX infrastructure to be able to take the SConscript file from one source
Expand All @@ -200,12 +199,12 @@ def equal_stats(x,y):
test.must_exist(test.workpath('build', 'var6', file))
test.fail_test(not equal_stats(test.workpath('build', 'var6', file),
test.workpath('test', 'src', file)))

# Make sure we didn't duplicate the source files in build/var7.
test.must_not_exist(test.workpath('build', 'var7', 'aaa.in'))
test.must_not_exist(test.workpath('build', 'var7', 'bbb.in'))
test.must_not_exist(test.workpath('build', 'var7', 'ccc.in'))

# Make sure we didn't duplicate the source files in build/var8.
test.must_not_exist(test.workpath('build', 'var8', 'aaa.in'))
test.must_not_exist(test.workpath('build', 'var8', 'bbb.in'))
Expand All @@ -219,6 +218,7 @@ def equal_stats(x,y):
""")

test.write(['test2', 'SConscript'], """\
DefaultEnvironment(tools=[]) # test speedup
env = Environment()
foo_obj = env.Object('foo.c')
env.Program('foo', [foo_obj, 'bar.c'])
Expand Down
Loading

0 comments on commit 9d5e76a

Please sign in to comment.