Add a variant of TemporaryDirectory that uses windows_proof_rmtree()
Adds TemporaryDirectoryWinProof which calls windows_proof_rmtree() on error. Use instead of hacky error handling (which might shadow other OSError) in Compiler.compile().
This commit is contained in:
parent
1db800bf67
commit
abc7e6af01
|
@ -13,7 +13,7 @@
|
|||
# limitations under the License.
|
||||
|
||||
import abc
|
||||
import contextlib, os.path, re, tempfile
|
||||
import contextlib, os.path, re
|
||||
import enum
|
||||
import itertools
|
||||
import typing as T
|
||||
|
@ -25,7 +25,7 @@ from .. import mesonlib
|
|||
from ..linkers import LinkerEnvVarsMixin
|
||||
from ..mesonlib import (
|
||||
EnvironmentException, MachineChoice, MesonException,
|
||||
Popen_safe, split_args, LibType
|
||||
Popen_safe, split_args, LibType, TemporaryDirectoryWinProof
|
||||
)
|
||||
from ..envconfig import (
|
||||
get_env_var
|
||||
|
@ -735,8 +735,8 @@ class Compiler(metaclass=abc.ABCMeta):
|
|||
# TODO: there isn't really any reason for this to be a contextmanager
|
||||
if extra_args is None:
|
||||
extra_args = []
|
||||
try:
|
||||
with tempfile.TemporaryDirectory(dir=temp_dir) as tmpdirname:
|
||||
|
||||
with TemporaryDirectoryWinProof(dir=temp_dir) as tmpdirname:
|
||||
no_ccache = False
|
||||
if isinstance(code, str):
|
||||
srcname = os.path.join(tmpdirname,
|
||||
|
@ -781,11 +781,6 @@ class Compiler(metaclass=abc.ABCMeta):
|
|||
if want_output:
|
||||
result.output_name = output
|
||||
yield result
|
||||
except OSError:
|
||||
# On Windows antivirus programs and the like hold on to files so
|
||||
# they can't be deleted. There's not much to do in this case. Also,
|
||||
# catch OSError because the directory is then no longer empty.
|
||||
return
|
||||
|
||||
@contextlib.contextmanager
|
||||
def cached_compile(self, code: str, cdata: coredata.CoreData, *,
|
||||
|
|
|
@ -22,6 +22,7 @@ import collections
|
|||
from enum import IntEnum
|
||||
from functools import lru_cache, wraps
|
||||
from itertools import tee, filterfalse
|
||||
from tempfile import TemporaryDirectory
|
||||
import typing as T
|
||||
import uuid
|
||||
import textwrap
|
||||
|
@ -1452,6 +1453,25 @@ def windows_proof_rm(fpath: str) -> None:
|
|||
os.unlink(fpath)
|
||||
|
||||
|
||||
class TemporaryDirectoryWinProof(TemporaryDirectory):
|
||||
"""
|
||||
Like TemporaryDirectory, but cleans things up using
|
||||
windows_proof_rmtree()
|
||||
"""
|
||||
|
||||
def __exit__(self, exc: T.Any, value: T.Any, tb: T.Any) -> None:
|
||||
try:
|
||||
super().__exit__(exc, value, tb)
|
||||
except OSError:
|
||||
windows_proof_rmtree(self.name)
|
||||
|
||||
def cleanup(self) -> None:
|
||||
try:
|
||||
super().cleanup()
|
||||
except OSError:
|
||||
windows_proof_rmtree(self.name)
|
||||
|
||||
|
||||
def detect_subprojects(spdir_name: str, current_dir: str = '',
|
||||
result: T.Optional[T.Dict[str, T.List[str]]] = None) -> T.Optional[T.Dict[str, T.List[str]]]:
|
||||
if result is None:
|
||||
|
|
Loading…
Reference in New Issue