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

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1#!/usr/bin/env python3
2# -*- coding: utf-8; mode: python; -*-
3# Copyright © 2021 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.
23"""
25import os
26from pathlib import Path
27from typing import Union
30def fs_perm(path: Path, mode: Union[int, str] = 0, **permargs):
31 """
32 Check read, write, execute permissions for effective id.
34 Args:
35 path: check permissions of this location
36 mode: permissions to check {[0-7],r,w,x,rw,wx,rx,rwx,}
37 **permargs:
39 All are passed to :py:meth:`os.access`
41 Defaults:
43 - effective_ids: ``True``
44 - follow_symlinks ``True``
46 Returns:
47 ``True`` only if permissions are available or if perm is ``0``
48 """
49 if mode in ('0', 0, ''):
50 return True
51 mode_letter = {'x': 1, 'w': 2, 'r': 4}
52 mode_code = (None, os.X_OK, os.W_OK, os.W_OK | os.X_OK, os.R_OK,
53 os.R_OK | os.X_OK, os.R_OK | os.W_OK,
54 os.R_OK | os.W_OK | os.X_OK)
56 # convert mode to octal
57 oct_mode = 0
58 try:
59 if isinstance(mode, str):
60 # new in 3.10, use match .. case
61 # convert to int
62 for p in list(mode):
63 oct_mode += mode_letter[p]
64 else:
65 # permissions as integer
66 oct_mode = mode % 8
67 _mode = mode_code[oct_mode]
68 except KeyError as err:
69 raise KeyError(f'{err}\nmode: ([0-7]|r|w|x|rw|wx|rx|rwx|)') from None
70 if _mode is None:
71 # this should never happen
72 # dummy check fallback
73 return True
74 while not path.exists():
75 path = path.parent
76 for default in ('follow_symlinks', 'effective_ids'):
77 permargs[default] = permargs.get(default, True)
78 return os.access(path, _mode, **permargs)
81def is_mount(path: Path):
82 """
83 Check across platform if path is mountpoint (unix) or drive (win).
85 Args:
86 path: path to be checked
87 """
88 try:
89 if path.is_mount():
90 return True
91 return False
92 except NotImplementedError: # pragma: no cover
93 if path.resolve().drive + '\\' == str(path):
94 return True
95 return False