dycw-utilities 0.168.6__py3-none-any.whl → 0.168.8__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.

Potentially problematic release.


This version of dycw-utilities might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.168.6
3
+ Version: 0.168.8
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -1,4 +1,4 @@
1
- utilities/__init__.py,sha256=BaEJrfp8I0sYX_vcN58wi7OQMMfRwxGWjtG8JsjrESg,60
1
+ utilities/__init__.py,sha256=8BrxDt-QtUtM996XvW_cg_FEoWgPD4pyI6UCzduaXpI,60
2
2
  utilities/aeventkit.py,sha256=OmDBhYGgbsKrB7cdC5FFpJHUatX9O76eTeKVVTksp2Y,12673
3
3
  utilities/altair.py,sha256=nHdpWt8ZwdUwRQN970MvHd5bRWokNqzHcZQEdSHKRuE,9033
4
4
  utilities/asyncio.py,sha256=60l1IwjnRGeaVphAFiwDIHyfKoZYKY-XGpptUxGiU-M,17034
@@ -21,6 +21,7 @@ utilities/functions.py,sha256=82qCAaPIB0JmZ5wsQurA3MTYl7fh8LHcoBFkxPs7Zeg,21478
21
21
  utilities/functools.py,sha256=I00ru2gQPakZw2SHVeKIKXfTv741655s6HI0lUoE0D4,1552
22
22
  utilities/getpass.py,sha256=DfN5UgMAtFCqS3dSfFHUfqIMZX2shXvwphOz_6J6f6A,103
23
23
  utilities/git.py,sha256=U1RFvCTANGENgx9wVBDvllioqBQZM2ns12ivKhOsaO4,414
24
+ utilities/grp.py,sha256=ax5oM-zQG2uiBbEXpFnI6YmV6NH2xRp65qSi6dVd5MI,712
24
25
  utilities/gzip.py,sha256=fkGP3KdsBfXlstodT4wtlp-PwNyUsogpbDCVVVGdsm4,781
25
26
  utilities/hashlib.py,sha256=SVTgtguur0P4elppvzOBbLEjVM3Pea0eWB61yg2ilxo,309
26
27
  utilities/http.py,sha256=TsavEfHlRtlLaeV21Z6KZh0qbPw-kvD1zsQdZ7Kep5Q,977
@@ -43,9 +44,9 @@ utilities/numpy.py,sha256=Xn23sA2ZbVNqwUYEgNJD3XBYH6IbCri_WkHSNhg3NkY,26122
43
44
  utilities/operator.py,sha256=C3NylZWGTVWRpwYHOPVhaLgRhw0DfpS4_XQ8KfPhBLQ,3613
44
45
  utilities/optuna.py,sha256=C-fhWYiXHVPo1l8QctYkFJ4DyhbSrGorzP1dJb_qvd8,1933
45
46
  utilities/orjson.py,sha256=PF1TUS3uR9wZH5iMkmv24arIH2TvrLKmpVRLMlVFm-o,41879
46
- utilities/os.py,sha256=MQxP4yVsV0sg8nPQyC8rctnimJdys_PvzxqDZfVzMMs,3935
47
+ utilities/os.py,sha256=kjKKSQfnRqFTTZ315iavaaGd3gGuYNoSWlxVLCJjyQs,4852
47
48
  utilities/parse.py,sha256=g7Qm9eBOIeDId2tGA021CIaeF6jp1TI8rx4srdvlyoo,17937
48
- utilities/pathlib.py,sha256=X6pHmfT3hnBGysdTr73uHsNaBEgKviZhk7aGWvEXDXo,8912
49
+ utilities/pathlib.py,sha256=EKZn-wWxH7MEWFrQGqHIoB-GJzyXeiEj8iDIgvkr8Wk,9325
49
50
  utilities/pickle.py,sha256=MBT2xZCsv0pH868IXLGKnlcqNx2IRVKYNpRcqiQQqxw,653
50
51
  utilities/platform.py,sha256=pTn7gw6N4T6LdKrf0virwarof_mze9WtoQlrGMzhGVI,2798
51
52
  utilities/polars.py,sha256=qsiYY9p_41fORGnc7HNkA4zhlsycK7sgD74xuigMDAc,87466
@@ -54,6 +55,7 @@ utilities/postgres.py,sha256=qQzXJngzs2jyZ4rkzL6uBdhXPwiqpPtYQiIonNcGIwI,12516
54
55
  utilities/pottery.py,sha256=nA0SsF9irvfC0tk68YAr08tuL9lGRSlBKihSx7Ibk84,3963
55
56
  utilities/pqdm.py,sha256=idv2seRVP2f6NeSfpeEnT5A-tQezaHZKDyeu16g2-0E,3091
56
57
  utilities/psutil.py,sha256=KUlu4lrUw9Zg1V7ZGetpWpGb9DB8l_SSDWGbANFNCPU,2104
58
+ utilities/pwd.py,sha256=pzlLkBfSTZsCVkMrAxEmuEoNmm-6goklfAygVmOEZqs,707
57
59
  utilities/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
60
  utilities/pydantic.py,sha256=z_PnYXN_UNNLQwo_XF7cr4GDcf5wicvscD6aFYVOEvA,238
59
61
  utilities/pydantic_settings.py,sha256=53tQTpHFtA6UIuzHKzauZtW_bSRwL5lQnNwTWeO4Fjw,7608
@@ -93,8 +95,8 @@ utilities/zoneinfo.py,sha256=tdIScrTB2-B-LH0ukb1HUXKooLknOfJNwHk10MuMYvA,3619
93
95
  utilities/pytest_plugins/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
94
96
  utilities/pytest_plugins/pytest_randomly.py,sha256=B1qYVlExGOxTywq2r1SMi5o7btHLk2PNdY_b1p98dkE,409
95
97
  utilities/pytest_plugins/pytest_regressions.py,sha256=mnHYBfdprz50UGVkVzV1bZERZN5CFfoF8YbokGxdFwU,1639
96
- dycw_utilities-0.168.6.dist-info/METADATA,sha256=eWJOwHgEwRvhX-UTRB2_2UB12BMvaVBOFdsb9meB4X4,1699
97
- dycw_utilities-0.168.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
98
- dycw_utilities-0.168.6.dist-info/entry_points.txt,sha256=BOD_SoDxwsfJYOLxhrSXhHP_T7iw-HXI9f2WVkzYxvQ,135
99
- dycw_utilities-0.168.6.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
100
- dycw_utilities-0.168.6.dist-info/RECORD,,
98
+ dycw_utilities-0.168.8.dist-info/METADATA,sha256=iY9Ato9xyYLZe3bfduvBeXvr6nHyI2Mygr8erECvOCk,1699
99
+ dycw_utilities-0.168.8.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
100
+ dycw_utilities-0.168.8.dist-info/entry_points.txt,sha256=BOD_SoDxwsfJYOLxhrSXhHP_T7iw-HXI9f2WVkzYxvQ,135
101
+ dycw_utilities-0.168.8.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
102
+ dycw_utilities-0.168.8.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.168.6"
3
+ __version__ = "0.168.8"
utilities/grp.py ADDED
@@ -0,0 +1,28 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import assert_never
4
+
5
+ from utilities.os import EFFECTIVE_GROUP_ID
6
+ from utilities.platform import SYSTEM
7
+
8
+
9
+ def get_gid_name(gid: int, /) -> str | None:
10
+ """Get the name of a group."""
11
+ match SYSTEM:
12
+ case "windows": # skipif-not-windows
13
+ return None
14
+ case "mac" | "linux": # skipif-windows
15
+ from grp import getgrgid
16
+
17
+ return getgrgid(gid).gr_name
18
+ case never:
19
+ assert_never(never)
20
+
21
+
22
+ ROOT_GROUP_NAME = get_gid_name(0)
23
+ EFFECTIVE_GROUP_NAME = (
24
+ None if EFFECTIVE_GROUP_ID is None else get_gid_name(EFFECTIVE_GROUP_ID)
25
+ )
26
+
27
+
28
+ __all__ = ["EFFECTIVE_GROUP_NAME", "ROOT_GROUP_NAME", "get_gid_name"]
utilities/os.py CHANGED
@@ -7,6 +7,7 @@ from typing import TYPE_CHECKING, Literal, assert_never, overload, override
7
7
 
8
8
  from utilities.contextlib import enhanced_context_manager
9
9
  from utilities.iterables import OneStrEmptyError, one_str
10
+ from utilities.platform import SYSTEM
10
11
 
11
12
  if TYPE_CHECKING:
12
13
  from collections.abc import Iterator, Mapping
@@ -124,6 +125,39 @@ class GetEnvVarError(Exception):
124
125
  ##
125
126
 
126
127
 
128
+ def get_effective_group_id() -> int | None:
129
+ """Get the effective group ID."""
130
+ match SYSTEM:
131
+ case "windows": # skipif-not-windows
132
+ return None
133
+ case "mac" | "linux": # skipif-windows
134
+ from os import getegid
135
+
136
+ return getegid()
137
+ case never:
138
+ assert_never(never)
139
+
140
+
141
+ def get_effective_user_id() -> int | None:
142
+ """Get the effective user ID."""
143
+ match SYSTEM:
144
+ case "windows": # skipif-not-windows
145
+ return None
146
+ case "mac" | "linux": # skipif-windows
147
+ from os import geteuid
148
+
149
+ return geteuid()
150
+ case never:
151
+ assert_never(never)
152
+
153
+
154
+ EFFECTIVE_USER_ID = get_effective_user_id()
155
+ EFFECTIVE_GROUP_ID = get_effective_group_id()
156
+
157
+
158
+ ##
159
+
160
+
127
161
  def is_debug() -> bool:
128
162
  """Check if we are in `DEBUG` mode."""
129
163
  return get_env_var("DEBUG", nullable=True) is not None
@@ -165,11 +199,15 @@ def temp_environ(
165
199
 
166
200
  __all__ = [
167
201
  "CPU_COUNT",
202
+ "EFFECTIVE_GROUP_ID",
203
+ "EFFECTIVE_USER_ID",
168
204
  "GetCPUCountError",
169
205
  "GetCPUUseError",
170
206
  "IntOrAll",
171
207
  "get_cpu_count",
172
208
  "get_cpu_use",
209
+ "get_effective_group_id",
210
+ "get_effective_user_id",
173
211
  "get_env_var",
174
212
  "is_debug",
175
213
  "is_pytest",
utilities/pathlib.py CHANGED
@@ -12,6 +12,8 @@ from typing import TYPE_CHECKING, Literal, assert_never, overload, override
12
12
 
13
13
  from utilities.contextlib import enhanced_context_manager
14
14
  from utilities.errors import ImpossibleCaseError
15
+ from utilities.grp import get_gid_name
16
+ from utilities.pwd import get_uid_name
15
17
  from utilities.sentinel import Sentinel
16
18
 
17
19
  if TYPE_CHECKING:
@@ -52,6 +54,19 @@ def expand_path(path: PathLike, /) -> Path:
52
54
  ##
53
55
 
54
56
 
57
+ def get_file_group(path: PathLike, /) -> str | None:
58
+ """Get the group of a file."""
59
+ return get_gid_name(to_path(path).stat().st_gid)
60
+
61
+
62
+ def get_file_owner(path: PathLike, /) -> str | None:
63
+ """Get the owner of a file."""
64
+ return get_uid_name(to_path(path).stat().st_uid)
65
+
66
+
67
+ ##
68
+
69
+
55
70
  def get_package_root(path: MaybeCallablePathLike = Path.cwd, /) -> Path:
56
71
  """Get the package root."""
57
72
  path = to_path(path)
@@ -327,6 +342,8 @@ __all__ = [
327
342
  "GetTailError",
328
343
  "ensure_suffix",
329
344
  "expand_path",
345
+ "get_file_group",
346
+ "get_file_owner",
330
347
  "get_package_root",
331
348
  "get_repo_root",
332
349
  "get_tail",
utilities/pwd.py ADDED
@@ -0,0 +1,28 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import assert_never
4
+
5
+ from utilities.os import EFFECTIVE_USER_ID
6
+ from utilities.platform import SYSTEM
7
+
8
+
9
+ def get_uid_name(uid: int, /) -> str | None:
10
+ """Get the name of a user ID."""
11
+ match SYSTEM:
12
+ case "windows": # skipif-not-windows
13
+ return None
14
+ case "mac" | "linux": # skipif-windows
15
+ from pwd import getpwuid
16
+
17
+ return getpwuid(uid).pw_name
18
+ case never:
19
+ assert_never(never)
20
+
21
+
22
+ ROOT_USER_NAME = get_uid_name(0)
23
+ EFFECTIVE_USER_NAME = (
24
+ None if EFFECTIVE_USER_ID is None else get_uid_name(EFFECTIVE_USER_ID)
25
+ )
26
+
27
+
28
+ __all__ = ["EFFECTIVE_USER_NAME", "ROOT_USER_NAME", "get_uid_name"]