diff options
author | Mats Wichmann <mats@linux.com> | 2025-03-10 16:22:54 (GMT) |
---|---|---|
committer | Mats Wichmann <mats@linux.com> | 2025-03-10 16:31:12 (GMT) |
commit | b1304d2004e7e575ce848f4e2157a05c7752a0ac (patch) | |
tree | 1eea0d35ca2cd78c707f4348010d9261fad92c14 | |
parent | 2e54b6f45bc7c461252f1295e4091c132315a2a9 (diff) | |
download | SCons-b1304d2004e7e575ce848f4e2157a05c7752a0ac.zip SCons-b1304d2004e7e575ce848f4e2157a05c7752a0ac.tar.gz SCons-b1304d2004e7e575ce848f4e2157a05c7752a0ac.tar.bz2 |
Fix CacheDir initialization so works on 3.7 also
Although there is no indication of a change in this area of the tempfile
module, it seems if the temporary directory has been renamed so the
original no longer exists, the context manager fails on 3.7, though
not on any later Python versions (maybe a bugfix rather than a planned
behavior change?). Now use mkdtemp instead, and clean it up by hand
if the rename failed (also use os.replace instead of os.rename,
so it will actually fail if the directory existed and is nonempty,
on Linux os.rename doesn't fail in this case).
Fixes #4694
Signed-off-by: Mats Wichmann <mats@linux.com>
-rw-r--r-- | CHANGES.txt | 2 | ||||
-rw-r--r-- | RELEASE.txt | 3 | ||||
-rw-r--r-- | SCons/CacheDir.py | 32 |
3 files changed, 24 insertions, 13 deletions
diff --git a/CHANGES.txt b/CHANGES.txt index d9b2e87..f1326e8 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -18,6 +18,8 @@ RELEASE VERSION/DATE TO BE FILLED IN LATER From Mats Wichmann: - Fix typos in CCFLAGS test. Didn't affect the test itself, but didn't correctly apply the DefaultEnvironment speedup. + - New CacheDir initialization code failed on Python 3.7 for unknown + reason (worked on 3.8+). Adjusted the approach a bit. Fixes #4694. RELEASE 4.9.0 - Sun, 02 Mar 2025 17:22:20 -0700 diff --git a/RELEASE.txt b/RELEASE.txt index 128daa1..e42847e 100644 --- a/RELEASE.txt +++ b/RELEASE.txt @@ -34,6 +34,9 @@ FIXES - List fixes of outright bugs +- New CacheDir initialization code failed on Python 3.7 for unknown + reason (worked on 3.8+). Adjusted the approach a bit. Fixes #4694. + IMPROVEMENTS ------------ diff --git a/SCons/CacheDir.py b/SCons/CacheDir.py index 25e3f66..3460fc3 100644 --- a/SCons/CacheDir.py +++ b/SCons/CacheDir.py @@ -27,6 +27,7 @@ import atexit import json import os +import shutil import stat import sys import tempfile @@ -76,7 +77,6 @@ def CacheRetrieveFunc(target, source, env) -> int: def CacheRetrieveString(target, source, env) -> str: t = target[0] - fs = t.fs cd = env.get_CacheDir() cachedir, cachefile = cd.cachepath(t) if t.fs.exists(cachefile): @@ -209,22 +209,28 @@ class CacheDir: if os.path.exists(directory): return False + # TODO: tried to use TemporaryDirectory() here and the result as a + # context manager, but that fails on Python 3.7 (works on 3.8+) after + # the directory has successfully been renamed. Not sure why. try: - tempdir = tempfile.TemporaryDirectory(dir=os.path.dirname(directory)) + tempdir = tempfile.mkdtemp(dir=os.path.dirname(directory)) except OSError as e: msg = "Failed to create cache directory " + path raise SCons.Errors.SConsEnvironmentError(msg) from e - self._add_config(tempdir.name) - with tempdir: - try: - os.rename(tempdir.name, directory) - return True - except Exception as e: - # did someone else get there first? - if os.path.isdir(directory): - return False - msg = "Failed to create cache directory " + path - raise SCons.Errors.SConsEnvironmentError(msg) from e + self._add_config(tempdir) + try: + os.replace(tempdir, directory) + return True + except OSError as e: + # did someone else get there first? attempt cleanup. + if os.path.isdir(directory): + try: + shutil.rmtree(tempdir) + except Exception: # we tried, don't worry about it + pass + return False + msg = "Failed to create cache directory " + path + raise SCons.Errors.SConsEnvironmentError(msg) from e def _readconfig(self, path: str) -> None: """Read the cache config from *path*. |