diff --git a/.appveyor.yml b/.appveyor.yml index 00dcb27432..0ad936fb59 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -8,7 +8,7 @@ image: # linux builds done in Travis CI for now - Visual Studio 2017 - Visual Studio 2019 - #- Visual Studio 2022 # Temporary disable while failing on 14.40 build tools + - Visual Studio 2022 cache: - downloads -> appveyor.yml @@ -35,36 +35,35 @@ environment: SCONS_CACHE_MSVC_CONFIG: "true" matrix: # Test oldest and newest supported Pythons, and a subset in between. - # Skipping 3.7 and 3.9 at this time - - WINPYTHON: "Python312" - - WINPYTHON: "Python310" - - WINPYTHON: "Python38" + # Skipping 3.8, 3.10, 3.12 at this time + - WINPYTHON: "Python313" + - WINPYTHON: "Python311" + - WINPYTHON: "Python39" - WINPYTHON: "Python37" # remove sets of build jobs based on criteria below # to fine tune the number and platforms tested matrix: exclude: - # XXX test python 3.6 on Visual Studio 2017 image - # test python 3.8 on Visual Studio 2017 image + # test python 3.7 on Visual Studio 2017 image - image: Visual Studio 2017 - WINPYTHON: "Python312" + WINPYTHON: "Python313" - image: Visual Studio 2017 - WINPYTHON: "Python310" + WINPYTHON: "Python311" + - image: Visual Studio 2017 + WINPYTHON: "Python39" - # test python 3.10 on Visual Studio 2019 image + # test python 3.9 on Visual Studio 2019 image - image: Visual Studio 2019 - WINPYTHON: "Python312" + WINPYTHON: "Python313" - image: Visual Studio 2019 - WINPYTHON: "Python38" + WINPYTHON: "Python311" - image: Visual Studio 2019 WINPYTHON: "Python37" - # test python 3.12 on Visual Studio 2022 image - - image: Visual Studio 2022 - WINPYTHON: "Python310" + # test python 3.11, 3.13 on Visual Studio 2022 image - image: Visual Studio 2022 - WINPYTHON: "Python38" + WINPYTHON: "Python39" - image: Visual Studio 2022 WINPYTHON: "Python37" diff --git a/CHANGES.txt b/CHANGES.txt index dc53457153..4fe15edf1a 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. - Try to fix Windows fails on Docbook tests in case xsltproc is found. It's still not certain why this started failing. On both GitHub Actions and AppVeyor, it's found as part of StrawberryPerl, part of diff --git a/RELEASE.txt b/RELEASE.txt index 128daa16fe..e42847e674 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 25e3f666f4..a5184b6e9c 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): @@ -210,21 +210,44 @@ def _mkdir_atomic(self, path: str) -> bool: return False try: - tempdir = tempfile.TemporaryDirectory(dir=os.path.dirname(directory)) + # TODO: Python 3.7. See comment below. + # 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 + + # TODO: Python 3.7: the context manager raises exception on cleanup + # if the temporary was moved successfully (File Not Found). + # Fixed in 3.8+. In the replacement below we manually clean up if + # the move failed as mkdtemp() does not. TemporaryDirectory's + # cleanup is more sophisitcated so prefer when we can use it. + # self._add_config(tempdir.name) + # with tempdir: + # try: + # os.replace(tempdir.name, directory) + # return True + # except OSError as e: + # # did someone else get there first? + # if os.path.isdir(directory): + # return False # context manager cleans up + # 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*.