Coverage for larch/utils/paths.py: 56%

68 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2024-10-16 21:04 +0000

1import sys 

2import os 

3import platform 

4from pathlib import Path 

5from charset_normalizer import from_bytes 

6 

7HAS_PWD = True 

8try: 

9 import pwd 

10except ImportError: 

11 HAS_PWD = False 

12 

13def unixpath(d): 

14 if isinstance(d, bytes): 

15 d = str(from_bytes(d).best()) 

16 if isinstance(d, str): 

17 d = Path(d).absolute() 

18 if isinstance(d, Path): 

19 return d.as_posix() 

20 raise ValueError(f"cannot get Path name from {d}") 

21 

22# uname = 'win', 'linux', or 'darwin' 

23uname = sys.platform.lower() 

24 

25if os.name == 'nt': 

26 uname = 'win' 

27if uname.startswith('linux'): 

28 uname = 'linux' 

29 

30def path_split(path): 

31 "emulate os.path.split, returning posix path and filename" 

32 p = Path(path).absolute() 

33 return p.parent.as_posix(), p.name 

34 

35# bindir = location of local binaries 

36nbits = platform.architecture()[0].replace('bit', '') 

37 

38_here = Path(__file__).absolute() 

39topdir = _here.parents[1].as_posix() 

40bindir = Path(topdir, 'bin', f"{uname}{nbits}").as_posix() 

41 

42 

43def get_homedir(): 

44 "determine home directory" 

45 homedir = None 

46 def check(method, s): 

47 "check that os.path.expanduser / expandvars gives a useful result" 

48 try: 

49 if method(s) not in (None, s): 

50 return method(s) 

51 except: 

52 pass 

53 return None 

54 

55 # for Unixes, allow for sudo case 

56 susername = os.environ.get("SUDO_USER", None) 

57 if HAS_PWD and susername is not None and homedir is None: 

58 try: 

59 homedir = pwd.getpwnam(susername).pw_dir 

60 except: 

61 homedir = None 

62 

63 # try expanding '~' -- should work on most Unixes 

64 if homedir is None: 

65 homedir = check(os.path.expanduser, '~') 

66 

67 # try the common environmental variables 

68 if homedir is None: 

69 for var in ('$HOME', '$HOMEPATH', '$USERPROFILE', '$ALLUSERSPROFILE'): 

70 homedir = check(os.path.expandvars, var) 

71 if homedir is not None: 

72 break 

73 

74 # For Windows, ask for parent of Roaming 'Application Data' directory 

75 if homedir is None and os.name == 'nt': 

76 try: 

77 from win32com.shell import shellcon, shell 

78 homedir = shell.SHGetFolderPath(0, shellcon.CSIDL_APPDATA, 0, 0) 

79 except ImportError: 

80 pass 

81 

82 # finally, use current folder 

83 if homedir is None: 

84 homedir = os.path.abspath('.') 

85 return unixpath(homedir) 

86 

87def get_cwd(): 

88 """get current working directory 

89 Note: os.getcwd() can fail with permission error. 

90 

91 when that happens, this changes to the users `HOME` directory 

92 and returns that directory so that it always returns an existing 

93 and readable directory. 

94 """ 

95 try: 

96 return Path('.').absolute().as_posix() 

97 except: 

98 home = get_homedir() 

99 os.chdir(home) 

100 return home