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
« 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
7HAS_PWD = True
8try:
9 import pwd
10except ImportError:
11 HAS_PWD = False
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}")
22# uname = 'win', 'linux', or 'darwin'
23uname = sys.platform.lower()
25if os.name == 'nt':
26 uname = 'win'
27if uname.startswith('linux'):
28 uname = 'linux'
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
35# bindir = location of local binaries
36nbits = platform.architecture()[0].replace('bit', '')
38_here = Path(__file__).absolute()
39topdir = _here.parents[1].as_posix()
40bindir = Path(topdir, 'bin', f"{uname}{nbits}").as_posix()
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
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
63 # try expanding '~' -- should work on most Unixes
64 if homedir is None:
65 homedir = check(os.path.expanduser, '~')
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
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
82 # finally, use current folder
83 if homedir is None:
84 homedir = os.path.abspath('.')
85 return unixpath(homedir)
87def get_cwd():
88 """get current working directory
89 Note: os.getcwd() can fail with permission error.
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