dycw-utilities 0.174.10__py3-none-any.whl → 0.174.11__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {dycw_utilities-0.174.10.dist-info → dycw_utilities-0.174.11.dist-info}/METADATA +1 -1
- {dycw_utilities-0.174.10.dist-info → dycw_utilities-0.174.11.dist-info}/RECORD +6 -6
- utilities/__init__.py +1 -1
- utilities/permissions.py +83 -59
- {dycw_utilities-0.174.10.dist-info → dycw_utilities-0.174.11.dist-info}/WHEEL +0 -0
- {dycw_utilities-0.174.10.dist-info → dycw_utilities-0.174.11.dist-info}/entry_points.txt +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
utilities/__init__.py,sha256=
|
|
1
|
+
utilities/__init__.py,sha256=Ed7ve87kqMRppt7gnxtu2swOV8yOK_hwjAE5eRBPgKg,61
|
|
2
2
|
utilities/aeventkit.py,sha256=OmDBhYGgbsKrB7cdC5FFpJHUatX9O76eTeKVVTksp2Y,12673
|
|
3
3
|
utilities/altair.py,sha256=rUK99g9x6CYDDfiZrf-aTx5fSRbL1Q8ctgKORowzXHg,9060
|
|
4
4
|
utilities/asyncio.py,sha256=aJySVxBY0gqsIYnoNmH7-1r8djKuf4vSsU69VCD08t8,16772
|
|
@@ -47,7 +47,7 @@ utilities/orjson.py,sha256=T_0SlK811ysg46d3orvIPY3JpBa4FRMpP2wlPQo7-gU,41854
|
|
|
47
47
|
utilities/os.py,sha256=kjKKSQfnRqFTTZ315iavaaGd3gGuYNoSWlxVLCJjyQs,4852
|
|
48
48
|
utilities/parse.py,sha256=g7Qm9eBOIeDId2tGA021CIaeF6jp1TI8rx4srdvlyoo,17937
|
|
49
49
|
utilities/pathlib.py,sha256=EKZn-wWxH7MEWFrQGqHIoB-GJzyXeiEj8iDIgvkr8Wk,9325
|
|
50
|
-
utilities/permissions.py,sha256=
|
|
50
|
+
utilities/permissions.py,sha256=xw3mDS5UT3SO5_AZ0RXYMQi1hU-3LedAWHdHEsOAHu0,8697
|
|
51
51
|
utilities/pickle.py,sha256=MBT2xZCsv0pH868IXLGKnlcqNx2IRVKYNpRcqiQQqxw,653
|
|
52
52
|
utilities/platform.py,sha256=0pYO5v7L2sU5UN87zHhEEhTKsZ9NIEM8N6UCr0F7bLY,2778
|
|
53
53
|
utilities/polars.py,sha256=cNFBLWgOMUAp_Sz4xtlto17uZswZRrcfQYC95QKyaY4,87483
|
|
@@ -98,7 +98,7 @@ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
|
|
|
98
98
|
utilities/whenever.py,sha256=F4ek0-OBWxHYrZdmoZt76N2RnNyKY5KrEHt7rqO4AQE,60183
|
|
99
99
|
utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
|
|
100
100
|
utilities/zoneinfo.py,sha256=tdIScrTB2-B-LH0ukb1HUXKooLknOfJNwHk10MuMYvA,3619
|
|
101
|
-
dycw_utilities-0.174.
|
|
102
|
-
dycw_utilities-0.174.
|
|
103
|
-
dycw_utilities-0.174.
|
|
104
|
-
dycw_utilities-0.174.
|
|
101
|
+
dycw_utilities-0.174.11.dist-info/WHEEL,sha256=ZyFSCYkV2BrxH6-HRVRg3R9Fo7MALzer9KiPYqNxSbo,79
|
|
102
|
+
dycw_utilities-0.174.11.dist-info/entry_points.txt,sha256=ykGI1ArwOPHqm2g5Cqh3ENdMxEej_a_FcOUov5EM5Oc,155
|
|
103
|
+
dycw_utilities-0.174.11.dist-info/METADATA,sha256=tBWZRVdVIvaeaLE3LYeGlWuwUcbt9ZOm0kunrxZj42Y,1710
|
|
104
|
+
dycw_utilities-0.174.11.dist-info/RECORD,,
|
utilities/__init__.py
CHANGED
utilities/permissions.py
CHANGED
|
@@ -14,15 +14,38 @@ from stat import (
|
|
|
14
14
|
S_IXOTH,
|
|
15
15
|
S_IXUSR,
|
|
16
16
|
)
|
|
17
|
-
from typing import Literal, Self, override
|
|
17
|
+
from typing import Literal, Self, assert_never, override
|
|
18
18
|
|
|
19
19
|
from utilities.dataclasses import replace_non_sentinel
|
|
20
20
|
from utilities.re import ExtractGroupsError, extract_groups
|
|
21
21
|
from utilities.sentinel import Sentinel, sentinel
|
|
22
22
|
|
|
23
|
+
type PermissionsLike = Permissions | int | str
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
##
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def ensure_perms(perms: PermissionsLike, /) -> Permissions:
|
|
30
|
+
"""Ensure a set of file permissions."""
|
|
31
|
+
match perms:
|
|
32
|
+
case Permissions():
|
|
33
|
+
return perms
|
|
34
|
+
case int():
|
|
35
|
+
return Permissions.from_int(perms)
|
|
36
|
+
case str():
|
|
37
|
+
return Permissions.from_text(perms)
|
|
38
|
+
case never:
|
|
39
|
+
assert_never(never)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
##
|
|
43
|
+
|
|
23
44
|
|
|
24
45
|
@dataclass(order=True, unsafe_hash=True, kw_only=True, slots=True)
|
|
25
46
|
class Permissions:
|
|
47
|
+
"""A set of file permissions."""
|
|
48
|
+
|
|
26
49
|
user_read: bool = False
|
|
27
50
|
user_write: bool = False
|
|
28
51
|
user_execute: bool = False
|
|
@@ -34,26 +57,18 @@ class Permissions:
|
|
|
34
57
|
others_execute: bool = False
|
|
35
58
|
|
|
36
59
|
def __int__(self) -> int:
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
execute=self.others_execute,
|
|
50
|
-
)
|
|
51
|
-
)
|
|
52
|
-
|
|
53
|
-
def _int(
|
|
54
|
-
self, *, read: bool = False, write: bool = False, execute: bool = False
|
|
55
|
-
) -> int:
|
|
56
|
-
return (4 if read else 0) + (2 if write else 0) + (1 if execute else 0)
|
|
60
|
+
flags: list[int] = [
|
|
61
|
+
S_IRUSR if self.user_read else 0,
|
|
62
|
+
S_IWUSR if self.user_write else 0,
|
|
63
|
+
S_IXUSR if self.user_execute else 0,
|
|
64
|
+
S_IRGRP if self.group_read else 0,
|
|
65
|
+
S_IWGRP if self.group_write else 0,
|
|
66
|
+
S_IXGRP if self.group_execute else 0,
|
|
67
|
+
S_IROTH if self.others_read else 0,
|
|
68
|
+
S_IWOTH if self.others_write else 0,
|
|
69
|
+
S_IXOTH if self.others_execute else 0,
|
|
70
|
+
]
|
|
71
|
+
return reduce(or_, flags)
|
|
57
72
|
|
|
58
73
|
@override
|
|
59
74
|
def __repr__(self) -> str:
|
|
@@ -87,13 +102,11 @@ class Permissions:
|
|
|
87
102
|
write: bool = False,
|
|
88
103
|
execute: bool = False,
|
|
89
104
|
) -> str:
|
|
90
|
-
parts: list[str] = [
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if execute:
|
|
96
|
-
parts.append("x")
|
|
105
|
+
parts: list[str] = [
|
|
106
|
+
"r" if read else "",
|
|
107
|
+
"w" if write else "",
|
|
108
|
+
"x" if execute else "",
|
|
109
|
+
]
|
|
97
110
|
return f"{prefix}={''.join(parts)}"
|
|
98
111
|
|
|
99
112
|
@override
|
|
@@ -101,12 +114,12 @@ class Permissions:
|
|
|
101
114
|
return repr(self)
|
|
102
115
|
|
|
103
116
|
@classmethod
|
|
104
|
-
def
|
|
117
|
+
def from_human_int(cls, n: int, /) -> Self:
|
|
105
118
|
if not (0 <= n <= 777):
|
|
106
|
-
raise
|
|
107
|
-
user_read, user_write, user_execute = cls.
|
|
108
|
-
group_read, group_write, group_execute = cls.
|
|
109
|
-
others_read, others_write, others_execute = cls.
|
|
119
|
+
raise PermissionsFromHumanIntRangeError(n=n)
|
|
120
|
+
user_read, user_write, user_execute = cls._from_human_int(n, (n // 100) % 10)
|
|
121
|
+
group_read, group_write, group_execute = cls._from_human_int(n, (n // 10) % 10)
|
|
122
|
+
others_read, others_write, others_execute = cls._from_human_int(n, n % 10)
|
|
110
123
|
return cls(
|
|
111
124
|
user_read=user_read,
|
|
112
125
|
user_write=user_write,
|
|
@@ -120,13 +133,13 @@ class Permissions:
|
|
|
120
133
|
)
|
|
121
134
|
|
|
122
135
|
@classmethod
|
|
123
|
-
def
|
|
136
|
+
def _from_human_int(cls, n: int, digit: int, /) -> tuple[bool, bool, bool]:
|
|
124
137
|
if not (0 <= digit <= 7):
|
|
125
|
-
raise
|
|
138
|
+
raise PermissionsFromHumanIntDigitError(n=n, digit=digit)
|
|
126
139
|
return bool(4 & digit), bool(2 & digit), bool(1 & digit)
|
|
127
140
|
|
|
128
141
|
@classmethod
|
|
129
|
-
def
|
|
142
|
+
def from_int(cls, n: int, /) -> Self:
|
|
130
143
|
if 0o0 <= n <= 0o777:
|
|
131
144
|
return cls(
|
|
132
145
|
user_read=bool(n & S_IRUSR),
|
|
@@ -139,7 +152,7 @@ class Permissions:
|
|
|
139
152
|
others_write=bool(n & S_IWOTH),
|
|
140
153
|
others_execute=bool(n & S_IXOTH),
|
|
141
154
|
)
|
|
142
|
-
raise
|
|
155
|
+
raise PermissionsFromIntError(n=n)
|
|
143
156
|
|
|
144
157
|
@classmethod
|
|
145
158
|
def from_text(cls, text: str, /) -> Self:
|
|
@@ -170,19 +183,27 @@ class Permissions:
|
|
|
170
183
|
return read != "", write != "", execute != ""
|
|
171
184
|
|
|
172
185
|
@property
|
|
173
|
-
def
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
+
def human_int(self) -> int:
|
|
187
|
+
return (
|
|
188
|
+
100
|
|
189
|
+
* self._human_int(
|
|
190
|
+
read=self.user_read, write=self.user_write, execute=self.user_execute
|
|
191
|
+
)
|
|
192
|
+
+ 10
|
|
193
|
+
* self._human_int(
|
|
194
|
+
read=self.group_read, write=self.group_write, execute=self.group_execute
|
|
195
|
+
)
|
|
196
|
+
+ self._human_int(
|
|
197
|
+
read=self.others_read,
|
|
198
|
+
write=self.others_write,
|
|
199
|
+
execute=self.others_execute,
|
|
200
|
+
)
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
def _human_int(
|
|
204
|
+
self, *, read: bool = False, write: bool = False, execute: bool = False
|
|
205
|
+
) -> int:
|
|
206
|
+
return (4 if read else 0) + (2 if write else 0) + (1 if execute else 0)
|
|
186
207
|
|
|
187
208
|
def replace(
|
|
188
209
|
self,
|
|
@@ -216,33 +237,35 @@ class PermissionsError(Exception): ...
|
|
|
216
237
|
|
|
217
238
|
|
|
218
239
|
@dataclass(kw_only=True, slots=True)
|
|
219
|
-
class
|
|
240
|
+
class PermissionsFromHumanIntError(PermissionsError):
|
|
220
241
|
n: int
|
|
221
242
|
|
|
222
243
|
|
|
223
244
|
@dataclass(kw_only=True, slots=True)
|
|
224
|
-
class
|
|
245
|
+
class PermissionsFromHumanIntRangeError(PermissionsFromHumanIntError):
|
|
225
246
|
@override
|
|
226
247
|
def __str__(self) -> str:
|
|
227
|
-
return f"Invalid integer for permissions; got {self.n}"
|
|
248
|
+
return f"Invalid human integer for permissions; got {self.n}"
|
|
228
249
|
|
|
229
250
|
|
|
230
251
|
@dataclass(kw_only=True, slots=True)
|
|
231
|
-
class
|
|
252
|
+
class PermissionsFromHumanIntDigitError(PermissionsFromHumanIntError):
|
|
232
253
|
digit: int
|
|
233
254
|
|
|
234
255
|
@override
|
|
235
256
|
def __str__(self) -> str:
|
|
236
|
-
return
|
|
257
|
+
return (
|
|
258
|
+
f"Invalid human integer for permissions; got digit {self.digit} in {self.n}"
|
|
259
|
+
)
|
|
237
260
|
|
|
238
261
|
|
|
239
262
|
@dataclass(kw_only=True, slots=True)
|
|
240
|
-
class
|
|
263
|
+
class PermissionsFromIntError(PermissionsError):
|
|
241
264
|
n: int
|
|
242
265
|
|
|
243
266
|
@override
|
|
244
267
|
def __str__(self) -> str:
|
|
245
|
-
return f"Invalid
|
|
268
|
+
return f"Invalid integer for permissions; got {self.n} = {oct(self.n)}"
|
|
246
269
|
|
|
247
270
|
|
|
248
271
|
@dataclass(kw_only=True, slots=True)
|
|
@@ -257,8 +280,9 @@ class PermissionsFromTextError(PermissionsError):
|
|
|
257
280
|
__all__ = [
|
|
258
281
|
"Permissions",
|
|
259
282
|
"PermissionsError",
|
|
260
|
-
"
|
|
283
|
+
"PermissionsFromHumanIntDigitError",
|
|
284
|
+
"PermissionsFromHumanIntError",
|
|
261
285
|
"PermissionsFromIntError",
|
|
262
|
-
"PermissionsFromOctalError",
|
|
263
286
|
"PermissionsFromTextError",
|
|
287
|
+
"ensure_perms",
|
|
264
288
|
]
|
|
File without changes
|
|
File without changes
|