jetpytools 2.2.1__tar.gz → 2.2.2__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.
- {jetpytools-2.2.1 → jetpytools-2.2.2}/PKG-INFO +1 -1
- jetpytools-2.2.2/jetpytools/_version.py +2 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/enums/base.py +1 -1
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/types/file.py +17 -15
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/types/utils.py +13 -6
- {jetpytools-2.2.1 → jetpytools-2.2.2}/pyproject.toml +1 -1
- jetpytools-2.2.1/jetpytools/_version.py +0 -2
- {jetpytools-2.2.1 → jetpytools-2.2.2}/.gitignore +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/LICENSE +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/README.md +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/__init__.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/enums/__init__.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/enums/other.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/exceptions/__init__.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/exceptions/base.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/exceptions/enum.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/exceptions/file.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/exceptions/generic.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/exceptions/module.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/functions/__init__.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/functions/funcs.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/functions/normalize.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/functions/other.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/py.typed +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/types/__init__.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/types/builtins.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/types/check.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/types/funcs.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/types/generic.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/types/supports.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/utils/__init__.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/utils/file.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/utils/funcs.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/utils/math.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/jetpytools/utils/ranges.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/tests/test_file.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/tests/test_funcs.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/tests/test_normalize.py +0 -0
- {jetpytools-2.2.1 → jetpytools-2.2.2}/tests/test_types_utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: jetpytools
|
|
3
|
-
Version: 2.2.
|
|
3
|
+
Version: 2.2.2
|
|
4
4
|
Summary: Collection of stuff that's useful in general python programming
|
|
5
5
|
Project-URL: Source Code, https://github.com/Jaded-Encoding-Thaumaturgy/jetpytools
|
|
6
6
|
Project-URL: Contact, https://discord.gg/XTpc6Fa9eB
|
|
@@ -71,7 +71,7 @@ class CustomEnum(Enum):
|
|
|
71
71
|
var_name=var_name,
|
|
72
72
|
enum_name=cls,
|
|
73
73
|
value=value,
|
|
74
|
-
readable_enum=(f"{name} ({value!
|
|
74
|
+
readable_enum=(f"{name} ({value!s})" for name, value in cls.__members__.items()),
|
|
75
75
|
reason=value,
|
|
76
76
|
) from None
|
|
77
77
|
|
|
@@ -132,7 +132,7 @@ class SPath(Path):
|
|
|
132
132
|
import shutil
|
|
133
133
|
|
|
134
134
|
try:
|
|
135
|
-
return shutil.rmtree(
|
|
135
|
+
return shutil.rmtree(self.get_folder(), ignore_errors)
|
|
136
136
|
except FileNotFoundError:
|
|
137
137
|
if not missing_ok:
|
|
138
138
|
raise
|
|
@@ -161,9 +161,11 @@ class SPath(Path):
|
|
|
161
161
|
|
|
162
162
|
return self.is_dir() and not any(self.iterdir())
|
|
163
163
|
|
|
164
|
-
def move_dir(self, dst:
|
|
164
|
+
def move_dir(self, dst: SPathLike, *, mode: int = 0o777) -> None:
|
|
165
165
|
"""Move the directory to the specified destination."""
|
|
166
166
|
|
|
167
|
+
dst = SPath(dst)
|
|
168
|
+
|
|
167
169
|
dst.mkdir(mode, True, True)
|
|
168
170
|
|
|
169
171
|
for file in listdir(self):
|
|
@@ -177,21 +179,22 @@ class SPath(Path):
|
|
|
177
179
|
|
|
178
180
|
self.rmdir()
|
|
179
181
|
|
|
180
|
-
def copy_dir(self, dst:
|
|
182
|
+
def copy_dir(self, dst: SPathLike) -> SPath:
|
|
181
183
|
"""Copy the directory to the specified destination."""
|
|
184
|
+
import shutil
|
|
182
185
|
|
|
183
186
|
if not self.is_dir():
|
|
184
187
|
from ..exceptions import PathIsNotADirectoryError
|
|
185
188
|
|
|
186
189
|
raise PathIsNotADirectoryError('The given path, "{self}" is not a directory!', self.copy_dir)
|
|
187
190
|
|
|
188
|
-
dst
|
|
191
|
+
dst = SPath(dst)
|
|
189
192
|
|
|
190
|
-
|
|
193
|
+
dst.mkdirp()
|
|
191
194
|
|
|
192
195
|
shutil.copytree(self, dst, dirs_exist_ok=True)
|
|
193
196
|
|
|
194
|
-
return
|
|
197
|
+
return dst
|
|
195
198
|
|
|
196
199
|
def lglob(self, pattern: str = "*") -> list[SPath]:
|
|
197
200
|
"""Glob the path and return the list of paths."""
|
|
@@ -209,17 +212,16 @@ class SPath(Path):
|
|
|
209
212
|
|
|
210
213
|
return None
|
|
211
214
|
|
|
212
|
-
def find_newest_file(
|
|
215
|
+
def find_newest_file(
|
|
216
|
+
self, pattern: str = "*", *, case_sensitive: bool | None = None, recurse_symlinks: bool = False
|
|
217
|
+
) -> SPath | None:
|
|
213
218
|
"""Find the most recently modified file matching the given pattern in the directory."""
|
|
214
219
|
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
return None
|
|
221
|
-
|
|
222
|
-
return max(matching_files, key=lambda p: p.stat().st_mtime)
|
|
220
|
+
return max(
|
|
221
|
+
self.get_folder().glob(pattern, case_sensitive=case_sensitive, recurse_symlinks=recurse_symlinks),
|
|
222
|
+
key=lambda p: p.stat().st_mtime,
|
|
223
|
+
default=None,
|
|
224
|
+
)
|
|
223
225
|
|
|
224
226
|
def get_size(self) -> int:
|
|
225
227
|
"""Get the size of the file or directory in bytes."""
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
import sys
|
|
4
4
|
from contextlib import suppress
|
|
5
5
|
from functools import wraps
|
|
6
|
+
from threading import Lock
|
|
6
7
|
from types import LambdaType
|
|
7
8
|
from typing import (
|
|
8
9
|
TYPE_CHECKING,
|
|
@@ -156,7 +157,7 @@ _P0 = ParamSpec("_P0")
|
|
|
156
157
|
_P1 = ParamSpec("_P1")
|
|
157
158
|
|
|
158
159
|
|
|
159
|
-
class _InjectedSelfFunc(Protocol[_T_co, _P, _R_co]):
|
|
160
|
+
class _InjectedSelfFunc(Protocol[_T_co, _P, _R_co]): # type: ignore[misc]
|
|
160
161
|
"""
|
|
161
162
|
Protocol defining the callable interface for wrapped functions under `inject_self`.
|
|
162
163
|
|
|
@@ -858,6 +859,8 @@ class KwargsNotNone(KwargsT):
|
|
|
858
859
|
|
|
859
860
|
class SingletonMeta(type):
|
|
860
861
|
_instances: ClassVar[dict[SingletonMeta, Any]] = {}
|
|
862
|
+
_lock = Lock()
|
|
863
|
+
|
|
861
864
|
_singleton_init: bool
|
|
862
865
|
|
|
863
866
|
def __new__[MetaSelf: SingletonMeta](
|
|
@@ -876,12 +879,16 @@ class SingletonMeta(type):
|
|
|
876
879
|
if not TYPE_CHECKING:
|
|
877
880
|
|
|
878
881
|
def __call__(cls, *args: Any, **kwargs: Any) -> Any:
|
|
879
|
-
if cls
|
|
880
|
-
cls._instances[cls]
|
|
881
|
-
|
|
882
|
+
if cls in cls._instances and not cls._singleton_init:
|
|
883
|
+
return cls._instances[cls]
|
|
884
|
+
|
|
885
|
+
with cls._lock:
|
|
886
|
+
if cls not in cls._instances:
|
|
887
|
+
cls._instances[cls] = obj = super().__call__(*args, **kwargs)
|
|
888
|
+
return obj
|
|
882
889
|
|
|
883
|
-
|
|
884
|
-
|
|
890
|
+
if cls._singleton_init:
|
|
891
|
+
cls._instances[cls].__init__(*args, **kwargs)
|
|
885
892
|
|
|
886
893
|
return cls._instances[cls]
|
|
887
894
|
|
|
@@ -25,7 +25,7 @@ dependencies = ["typing_extensions>=4.15.0; python_version<'3.13'"]
|
|
|
25
25
|
"Contact" = "https://discord.gg/XTpc6Fa9eB"
|
|
26
26
|
|
|
27
27
|
[dependency-groups]
|
|
28
|
-
dev = ["mypy~=1.
|
|
28
|
+
dev = ["mypy~=1.19.0", "ruff~=0.14.0", "pytest>=9.0.0, <10.0.0", "twine>=6.2.0"]
|
|
29
29
|
|
|
30
30
|
[build-system]
|
|
31
31
|
requires = ["hatchling>=1.27.0", "versioningit"]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|