dycw-utilities 0.174.9__tar.gz → 0.174.10__tar.gz

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.
Files changed (103) hide show
  1. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/PKG-INFO +1 -1
  2. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/pyproject.toml +2 -2
  3. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/__init__.py +1 -1
  4. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/permissions.py +36 -69
  5. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/README.md +0 -0
  6. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/aeventkit.py +0 -0
  7. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/altair.py +0 -0
  8. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/asyncio.py +0 -0
  9. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/atomicwrites.py +0 -0
  10. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/atools.py +0 -0
  11. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/cachetools.py +0 -0
  12. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/click.py +0 -0
  13. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/concurrent.py +0 -0
  14. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/contextlib.py +0 -0
  15. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/contextvars.py +0 -0
  16. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/cryptography.py +0 -0
  17. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/cvxpy.py +0 -0
  18. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/dataclasses.py +0 -0
  19. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/docker.py +0 -0
  20. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/enum.py +0 -0
  21. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/errors.py +0 -0
  22. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/fastapi.py +0 -0
  23. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/fpdf2.py +0 -0
  24. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/functions.py +0 -0
  25. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/functools.py +0 -0
  26. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/getpass.py +0 -0
  27. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/git.py +0 -0
  28. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/grp.py +0 -0
  29. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/gzip.py +0 -0
  30. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/hashlib.py +0 -0
  31. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/http.py +0 -0
  32. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/hypothesis.py +0 -0
  33. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/importlib.py +0 -0
  34. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/inflect.py +0 -0
  35. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/ipython.py +0 -0
  36. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/iterables.py +0 -0
  37. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/jinja2.py +0 -0
  38. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/json.py +0 -0
  39. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/jupyter.py +0 -0
  40. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/libcst.py +0 -0
  41. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/lightweight_charts.py +0 -0
  42. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/logging.py +0 -0
  43. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/math.py +0 -0
  44. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/memory_profiler.py +0 -0
  45. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/modules.py +0 -0
  46. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/more_itertools.py +0 -0
  47. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/numpy.py +0 -0
  48. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/operator.py +0 -0
  49. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/optuna.py +0 -0
  50. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/orjson.py +0 -0
  51. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/os.py +0 -0
  52. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/parse.py +0 -0
  53. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/pathlib.py +0 -0
  54. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/pickle.py +0 -0
  55. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/platform.py +0 -0
  56. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/polars.py +0 -0
  57. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/polars_ols.py +0 -0
  58. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/postgres.py +0 -0
  59. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/pottery.py +0 -0
  60. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/pqdm.py +0 -0
  61. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/psutil.py +0 -0
  62. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/pwd.py +0 -0
  63. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/py.typed +0 -0
  64. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/pydantic.py +0 -0
  65. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/pydantic_settings.py +0 -0
  66. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/pydantic_settings_sops.py +0 -0
  67. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/pyinstrument.py +0 -0
  68. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/pytest.py +0 -0
  69. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/pytest_plugins/__init__.py +0 -0
  70. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/pytest_plugins/pytest_randomly.py +0 -0
  71. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/pytest_plugins/pytest_regressions.py +0 -0
  72. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/pytest_regressions.py +0 -0
  73. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/random.py +0 -0
  74. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/re.py +0 -0
  75. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/redis.py +0 -0
  76. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/reprlib.py +0 -0
  77. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/scipy.py +0 -0
  78. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/sentinel.py +0 -0
  79. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/shelve.py +0 -0
  80. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/shutil.py +0 -0
  81. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/slack_sdk.py +0 -0
  82. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/socket.py +0 -0
  83. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/sqlalchemy.py +0 -0
  84. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/sqlalchemy_polars.py +0 -0
  85. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/statsmodels.py +0 -0
  86. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/string.py +0 -0
  87. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/subprocess.py +0 -0
  88. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/tempfile.py +0 -0
  89. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/testbook.py +0 -0
  90. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/text.py +0 -0
  91. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/threading.py +0 -0
  92. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/timer.py +0 -0
  93. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/traceback.py +0 -0
  94. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/types.py +0 -0
  95. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/typing.py +0 -0
  96. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/tzdata.py +0 -0
  97. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/tzlocal.py +0 -0
  98. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/uuid.py +0 -0
  99. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/version.py +0 -0
  100. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/warnings.py +0 -0
  101. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/whenever.py +0 -0
  102. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/zipfile.py +0 -0
  103. {dycw_utilities-0.174.9 → dycw_utilities-0.174.10}/src/utilities/zoneinfo.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: dycw-utilities
3
- Version: 0.174.9
3
+ Version: 0.174.10
4
4
  Author: Derek Wan
5
5
  Author-email: Derek Wan <d.wan@icloud.com>
6
6
  Requires-Dist: atomicwrites>=1.4.1,<1.5
@@ -101,7 +101,7 @@
101
101
  name = "dycw-utilities"
102
102
  readme = "README.md"
103
103
  requires-python = ">= 3.12"
104
- version = "0.174.9"
104
+ version = "0.174.10"
105
105
 
106
106
  [project.entry-points.pytest11]
107
107
  pytest-randomly = "utilities.pytest_plugins.pytest_randomly"
@@ -135,7 +135,7 @@
135
135
  # bump-my-version
136
136
  [tool.bumpversion]
137
137
  allow_dirty = true
138
- current_version = "0.174.9"
138
+ current_version = "0.174.10"
139
139
 
140
140
  [[tool.bumpversion.files]]
141
141
  filename = "src/utilities/__init__.py"
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.174.9"
3
+ __version__ = "0.174.10"
@@ -1,6 +1,5 @@
1
1
  from __future__ import annotations
2
2
 
3
- from contextlib import suppress
4
3
  from dataclasses import dataclass
5
4
  from functools import reduce
6
5
  from operator import or_
@@ -18,20 +17,8 @@ from stat import (
18
17
  from typing import Literal, Self, override
19
18
 
20
19
  from utilities.dataclasses import replace_non_sentinel
21
- from utilities.functions import ensure_member
22
- from utilities.re import (
23
- ExtractGroupError,
24
- ExtractGroupsError,
25
- extract_group,
26
- extract_groups,
27
- )
20
+ from utilities.re import ExtractGroupsError, extract_groups
28
21
  from utilities.sentinel import Sentinel, sentinel
29
- from utilities.typing import get_args
30
-
31
- _MIN_INT = 0o0
32
- _MAX_INT = 0o777
33
- type _ZeroToSeven = Literal[0, 1, 2, 3, 4, 5, 6, 7]
34
- _ZERO_TO_SEVEN: list[_ZeroToSeven] = list(get_args(_ZeroToSeven.__value__))
35
22
 
36
23
 
37
24
  @dataclass(order=True, unsafe_hash=True, kw_only=True, slots=True)
@@ -65,7 +52,7 @@ class Permissions:
65
52
 
66
53
  def _int(
67
54
  self, *, read: bool = False, write: bool = False, execute: bool = False
68
- ) -> _ZeroToSeven:
55
+ ) -> int:
69
56
  return (4 if read else 0) + (2 if write else 0) + (1 if execute else 0)
70
57
 
71
58
  @override
@@ -115,65 +102,32 @@ class Permissions:
115
102
 
116
103
  @classmethod
117
104
  def from_int(cls, n: int, /) -> Self:
118
- with suppress(ExtractGroupsError):
119
- user, group, others = extract_groups(r"^([0-7])([0-7])([0-7])$", str(n))
120
- user_read, user_write, user_execute = cls._from_int(
121
- ensure_member(int(user), _ZERO_TO_SEVEN)
122
- )
123
- group_read, group_write, group_execute = cls._from_int(
124
- ensure_member(int(group), _ZERO_TO_SEVEN)
125
- )
126
- others_read, others_write, others_execute = cls._from_int(
127
- ensure_member(int(others), _ZERO_TO_SEVEN)
128
- )
129
- return cls(
130
- user_read=user_read,
131
- user_write=user_write,
132
- user_execute=user_execute,
133
- group_read=group_read,
134
- group_write=group_write,
135
- group_execute=group_execute,
136
- others_read=others_read,
137
- others_write=others_write,
138
- others_execute=others_execute,
139
- )
140
- with suppress(ExtractGroupsError):
141
- group, others = extract_groups(r"^([0-7])([0-7])$", str(n))
142
- group_read, group_write, group_execute = cls._from_int(
143
- ensure_member(int(group), _ZERO_TO_SEVEN)
144
- )
145
- others_read, others_write, others_execute = cls._from_int(
146
- ensure_member(int(others), _ZERO_TO_SEVEN)
147
- )
148
- return cls(
149
- group_read=group_read,
150
- group_write=group_write,
151
- group_execute=group_execute,
152
- others_read=others_read,
153
- others_write=others_write,
154
- others_execute=others_execute,
155
- )
156
- with suppress(ExtractGroupError):
157
- others = extract_group(r"^([0-7])$", str(n))
158
- others_read, others_write, others_execute = cls._from_int(
159
- ensure_member(int(others), _ZERO_TO_SEVEN)
160
- )
161
- return cls(
162
- others_read=others_read,
163
- others_write=others_write,
164
- others_execute=others_execute,
165
- )
166
- if n == 0:
167
- return cls()
168
- raise PermissionsFromIntError(n=n)
105
+ if not (0 <= n <= 777):
106
+ raise PermissionsFromIntRangeError(n=n)
107
+ user_read, user_write, user_execute = cls._from_int(n, (n // 100) % 10)
108
+ group_read, group_write, group_execute = cls._from_int(n, (n // 10) % 10)
109
+ others_read, others_write, others_execute = cls._from_int(n, n % 10)
110
+ return cls(
111
+ user_read=user_read,
112
+ user_write=user_write,
113
+ user_execute=user_execute,
114
+ group_read=group_read,
115
+ group_write=group_write,
116
+ group_execute=group_execute,
117
+ others_read=others_read,
118
+ others_write=others_write,
119
+ others_execute=others_execute,
120
+ )
169
121
 
170
122
  @classmethod
171
- def _from_int(cls, n: _ZeroToSeven, /) -> tuple[bool, bool, bool]:
172
- return bool(4 & n), bool(2 & n), bool(1 & n)
123
+ def _from_int(cls, n: int, digit: int, /) -> tuple[bool, bool, bool]:
124
+ if not (0 <= digit <= 7):
125
+ raise PermissionsFromIntDigitError(n=n, digit=digit)
126
+ return bool(4 & digit), bool(2 & digit), bool(1 & digit)
173
127
 
174
128
  @classmethod
175
129
  def from_octal(cls, n: int, /) -> Self:
176
- if _MIN_INT <= n <= _MAX_INT:
130
+ if 0o0 <= n <= 0o777:
177
131
  return cls(
178
132
  user_read=bool(n & S_IRUSR),
179
133
  user_write=bool(n & S_IWUSR),
@@ -265,11 +219,23 @@ class PermissionsError(Exception): ...
265
219
  class PermissionsFromIntError(PermissionsError):
266
220
  n: int
267
221
 
222
+
223
+ @dataclass(kw_only=True, slots=True)
224
+ class PermissionsFromIntRangeError(PermissionsFromIntError):
268
225
  @override
269
226
  def __str__(self) -> str:
270
227
  return f"Invalid integer for permissions; got {self.n}"
271
228
 
272
229
 
230
+ @dataclass(kw_only=True, slots=True)
231
+ class PermissionsFromIntDigitError(PermissionsFromIntError):
232
+ digit: int
233
+
234
+ @override
235
+ def __str__(self) -> str:
236
+ return f"Invalid integer for permissions; got digit {self.digit} in {self.n}"
237
+
238
+
273
239
  @dataclass(kw_only=True, slots=True)
274
240
  class PermissionsFromOctalError(PermissionsError):
275
241
  n: int
@@ -291,6 +257,7 @@ class PermissionsFromTextError(PermissionsError):
291
257
  __all__ = [
292
258
  "Permissions",
293
259
  "PermissionsError",
260
+ "PermissionsFromIntDigitError",
294
261
  "PermissionsFromIntError",
295
262
  "PermissionsFromOctalError",
296
263
  "PermissionsFromTextError",