Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/filelock/_util.py: 48%

21 statements  

« prev     ^ index     » next       coverage.py v7.3.1, created at 2023-09-25 06:08 +0000

1from __future__ import annotations 

2 

3import os 

4import stat 

5import sys 

6from errno import EACCES, EISDIR 

7from pathlib import Path 

8 

9 

10def raise_on_not_writable_file(filename: str) -> None: 

11 """ 

12 Raise an exception if attempting to open the file for writing would fail. 

13 This is done so files that will never be writable can be separated from 

14 files that are writable but currently locked 

15 :param filename: file to check 

16 :raises OSError: as if the file was opened for writing. 

17 """ 

18 try: # use stat to do exists + can write to check without race condition 

19 file_stat = os.stat(filename) # noqa: PTH116 

20 except OSError: 

21 return # swallow does not exist or other errors 

22 

23 if file_stat.st_mtime != 0: # if os.stat returns but modification is zero that's an invalid os.stat - ignore it 

24 if not (file_stat.st_mode & stat.S_IWUSR): 

25 raise PermissionError(EACCES, "Permission denied", filename) 

26 

27 if stat.S_ISDIR(file_stat.st_mode): 

28 if sys.platform == "win32": # pragma: win32 cover 

29 # On Windows, this is PermissionError 

30 raise PermissionError(EACCES, "Permission denied", filename) 

31 else: # pragma: win32 no cover # noqa: RET506 

32 # On linux / macOS, this is IsADirectoryError 

33 raise IsADirectoryError(EISDIR, "Is a directory", filename) 

34 

35 

36def ensure_directory_exists(filename: Path | str) -> None: 

37 """ 

38 Ensure the directory containing the file exists (create it if necessary) 

39 :param filename: file. 

40 """ 

41 Path(filename).parent.mkdir(parents=True, exist_ok=True) 

42 

43 

44__all__ = [ 

45 "raise_on_not_writable_file", 

46 "ensure_directory_exists", 

47]