Coverage for /home/pradyumna/Languages/python/packages/xdgpspconf/xdgpspconf/utils.py: 100%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

26 statements  

1#!/usr/bin/env python3 

2# -*- coding: utf-8; mode: python; -*- 

3# Copyright © 2021, 2022 Pradyumna Paranjape 

4# 

5# This file is part of xdgpspconf. 

6# 

7# xdgpspconf is free software: you can redistribute it and/or modify 

8# it under the terms of the GNU Lesser General Public License as published by 

9# the Free Software Foundation, either version 3 of the License, or 

10# (at your option) any later version. 

11# 

12# xdgpspconf is distributed in the hope that it will be useful, 

13# but WITHOUT ANY WARRANTY; without even the implied warranty of 

14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

15# GNU Lesser General Public License for more details. 

16# 

17# You should have received a copy of the GNU Lesser General Public License 

18# along with xdgpspconf. If not, see <https://www.gnu.org/licenses/>. 

19# 

20""" 

21Common filesystem discovery functions. 

22 

23""" 

24 

25import os 

26from functools import reduce 

27from pathlib import Path 

28from typing import Union 

29 

30 

31def fs_perm(path: Path, mode: Union[int, str] = 0, **permargs): 

32 """ 

33 Check read, write, execute permissions for effective id. 

34 

35 Args: 

36 path: check permissions of this location or latest existing ancestor. 

37 mode: permissions to check {[0-7],r,w,x,rw,wx,rx,rwx,} 

38 **permargs: 

39 

40 All are passed to :py:meth:`os.access` 

41 

42 Defaults: 

43 

44 - effective_ids: ``True`` 

45 - follow_symlinks ``True`` 

46 

47 Returns: 

48 ``True`` only if permissions are available 

49 """ 

50 mode_letter = {'x': 1, 'w': 2, 'r': 4, '-': 0} 

51 mode_code = (os.F_OK, os.X_OK, os.W_OK, os.W_OK | os.X_OK, os.R_OK, 

52 os.R_OK | os.X_OK, os.R_OK | os.W_OK, 

53 os.R_OK | os.W_OK | os.X_OK) 

54 

55 # convert mode to octal 

56 oct_mode = 0 

57 try: 

58 if isinstance(mode, str): 

59 # NEXT: in 3.10, use match .. case 

60 # convert to int 

61 oct_mode = reduce(lambda x, y: x | mode_letter[y], mode, 0) 

62 else: 

63 # permissions supplied as integer 

64 oct_mode = mode % 8 

65 _mode = mode_code[oct_mode] 

66 except KeyError as err: 

67 raise KeyError(f'{err}\nmode: ([0-7]|r|w|x|rw|wx|rx|rwx|)') from None 

68 while not path.exists(): 

69 path = path.parent 

70 for default in ('follow_symlinks', 'effective_ids'): 

71 permargs[default] = permargs.get(default, True) 

72 return os.access(path, _mode, **permargs) 

73 

74 

75def is_mount(path: Path): 

76 """ 

77 Check across platform if path is mountpoint (unix) or drive (win). 

78 

79 Args: 

80 path: path to be checked 

81 """ 

82 try: 

83 if path.is_mount(): 

84 return True 

85 return False 

86 except NotImplementedError: # pragma: no cover 

87 if path.resolve().drive + '\\' == str(path): 

88 return True 

89 return False