dycw-utilities 0.129.10__py3-none-any.whl → 0.175.17__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.175.17.dist-info/METADATA +34 -0
- dycw_utilities-0.175.17.dist-info/RECORD +103 -0
- dycw_utilities-0.175.17.dist-info/WHEEL +4 -0
- dycw_utilities-0.175.17.dist-info/entry_points.txt +4 -0
- utilities/__init__.py +1 -1
- utilities/altair.py +14 -14
- utilities/asyncio.py +350 -819
- utilities/atomicwrites.py +18 -6
- utilities/atools.py +77 -22
- utilities/cachetools.py +24 -29
- utilities/click.py +393 -237
- utilities/concurrent.py +8 -11
- utilities/contextlib.py +216 -17
- utilities/contextvars.py +20 -1
- utilities/cryptography.py +3 -3
- utilities/dataclasses.py +83 -118
- utilities/docker.py +293 -0
- utilities/enum.py +26 -23
- utilities/errors.py +17 -3
- utilities/fastapi.py +29 -65
- utilities/fpdf2.py +3 -3
- utilities/functions.py +169 -416
- utilities/functools.py +18 -19
- utilities/git.py +9 -30
- utilities/grp.py +28 -0
- utilities/gzip.py +31 -0
- utilities/http.py +3 -2
- utilities/hypothesis.py +738 -589
- utilities/importlib.py +17 -1
- utilities/inflect.py +25 -0
- utilities/iterables.py +194 -262
- utilities/jinja2.py +148 -0
- utilities/json.py +70 -0
- utilities/libcst.py +38 -17
- utilities/lightweight_charts.py +5 -9
- utilities/logging.py +345 -543
- utilities/math.py +18 -13
- utilities/memory_profiler.py +11 -15
- utilities/more_itertools.py +200 -131
- utilities/operator.py +33 -29
- utilities/optuna.py +6 -6
- utilities/orjson.py +272 -137
- utilities/os.py +61 -4
- utilities/parse.py +59 -61
- utilities/pathlib.py +281 -40
- utilities/permissions.py +298 -0
- utilities/pickle.py +2 -2
- utilities/platform.py +24 -5
- utilities/polars.py +1214 -430
- utilities/polars_ols.py +1 -1
- utilities/postgres.py +408 -0
- utilities/pottery.py +113 -26
- utilities/pqdm.py +10 -11
- utilities/psutil.py +6 -57
- utilities/pwd.py +28 -0
- utilities/pydantic.py +4 -54
- utilities/pydantic_settings.py +240 -0
- utilities/pydantic_settings_sops.py +76 -0
- utilities/pyinstrument.py +8 -10
- utilities/pytest.py +227 -121
- utilities/pytest_plugins/__init__.py +1 -0
- utilities/pytest_plugins/pytest_randomly.py +23 -0
- utilities/pytest_plugins/pytest_regressions.py +56 -0
- utilities/pytest_regressions.py +26 -46
- utilities/random.py +13 -9
- utilities/re.py +58 -28
- utilities/redis.py +401 -550
- utilities/scipy.py +1 -1
- utilities/sentinel.py +10 -0
- utilities/shelve.py +4 -1
- utilities/shutil.py +25 -0
- utilities/slack_sdk.py +36 -106
- utilities/sqlalchemy.py +502 -473
- utilities/sqlalchemy_polars.py +38 -94
- utilities/string.py +2 -3
- utilities/subprocess.py +1572 -0
- utilities/tempfile.py +86 -4
- utilities/testbook.py +50 -0
- utilities/text.py +165 -42
- utilities/timer.py +37 -65
- utilities/traceback.py +158 -929
- utilities/types.py +146 -116
- utilities/typing.py +531 -71
- utilities/tzdata.py +1 -53
- utilities/tzlocal.py +6 -23
- utilities/uuid.py +43 -5
- utilities/version.py +27 -26
- utilities/whenever.py +1776 -386
- utilities/zoneinfo.py +84 -22
- dycw_utilities-0.129.10.dist-info/METADATA +0 -241
- dycw_utilities-0.129.10.dist-info/RECORD +0 -96
- dycw_utilities-0.129.10.dist-info/WHEEL +0 -4
- dycw_utilities-0.129.10.dist-info/licenses/LICENSE +0 -21
- utilities/datetime.py +0 -1409
- utilities/eventkit.py +0 -402
- utilities/loguru.py +0 -144
- utilities/luigi.py +0 -228
- utilities/period.py +0 -324
- utilities/pyrsistent.py +0 -89
- utilities/python_dotenv.py +0 -105
- utilities/streamlit.py +0 -105
- utilities/sys.py +0 -87
- utilities/tenacity.py +0 -145
utilities/operator.py
CHANGED
|
@@ -1,35 +1,27 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import datetime as dt
|
|
4
3
|
from collections.abc import Callable, Mapping, Sequence
|
|
5
4
|
from collections.abc import Set as AbstractSet
|
|
6
5
|
from dataclasses import asdict, dataclass
|
|
7
|
-
from typing import TYPE_CHECKING, Any,
|
|
6
|
+
from typing import TYPE_CHECKING, Any, cast, override
|
|
8
7
|
|
|
9
8
|
import utilities.math
|
|
10
|
-
from utilities.datetime import (
|
|
11
|
-
AreEqualDatesOrDateTimesError,
|
|
12
|
-
AreEqualDateTimesError,
|
|
13
|
-
are_equal_dates_or_datetimes,
|
|
14
|
-
)
|
|
15
|
-
from utilities.functions import is_dataclass_instance
|
|
16
9
|
from utilities.iterables import SortIterableError, sort_iterable
|
|
17
10
|
from utilities.reprlib import get_repr
|
|
11
|
+
from utilities.typing import is_dataclass_instance
|
|
18
12
|
|
|
19
13
|
if TYPE_CHECKING:
|
|
20
|
-
from utilities.types import Dataclass,
|
|
14
|
+
from utilities.types import Dataclass, Number
|
|
21
15
|
|
|
22
|
-
_T = TypeVar("_T")
|
|
23
16
|
|
|
24
|
-
|
|
25
|
-
def is_equal(
|
|
17
|
+
def is_equal[T](
|
|
26
18
|
x: Any,
|
|
27
19
|
y: Any,
|
|
28
20
|
/,
|
|
29
21
|
*,
|
|
30
22
|
rel_tol: float | None = None,
|
|
31
23
|
abs_tol: float | None = None,
|
|
32
|
-
extra: Mapping[type[
|
|
24
|
+
extra: Mapping[type[T], Callable[[T, T], bool]] | None = None,
|
|
33
25
|
) -> bool:
|
|
34
26
|
"""Check if two objects are equal."""
|
|
35
27
|
if type(x) is type(y):
|
|
@@ -40,8 +32,8 @@ def is_equal(
|
|
|
40
32
|
except StopIteration:
|
|
41
33
|
pass
|
|
42
34
|
else:
|
|
43
|
-
x = cast("
|
|
44
|
-
y = cast("
|
|
35
|
+
x = cast("T", x)
|
|
36
|
+
y = cast("T", y)
|
|
45
37
|
return cmp(x, y)
|
|
46
38
|
|
|
47
39
|
# singletons
|
|
@@ -51,12 +43,6 @@ def is_equal(
|
|
|
51
43
|
if isinstance(x, str): # else Sequence
|
|
52
44
|
y = cast("str", y)
|
|
53
45
|
return x == y
|
|
54
|
-
if isinstance(x, dt.date | dt.datetime):
|
|
55
|
-
y = cast("DateOrDateTime", y)
|
|
56
|
-
try:
|
|
57
|
-
return are_equal_dates_or_datetimes(x, y)
|
|
58
|
-
except (AreEqualDateTimesError, AreEqualDatesOrDateTimesError):
|
|
59
|
-
return False
|
|
60
46
|
if is_dataclass_instance(x):
|
|
61
47
|
y = cast("Dataclass", y)
|
|
62
48
|
x_values = asdict(x)
|
|
@@ -66,6 +52,14 @@ def is_equal(
|
|
|
66
52
|
return is_equal(x.args, y.args)
|
|
67
53
|
|
|
68
54
|
# collections
|
|
55
|
+
if isinstance(x, AbstractSet):
|
|
56
|
+
y = cast("AbstractSet[Any]", y)
|
|
57
|
+
try:
|
|
58
|
+
x_sorted = sort_iterable(x)
|
|
59
|
+
y_sorted = sort_iterable(y)
|
|
60
|
+
except SortIterableError:
|
|
61
|
+
return _is_in(x, y) and _is_in(y, x)
|
|
62
|
+
return is_equal(x_sorted, y_sorted, rel_tol=rel_tol, abs_tol=abs_tol)
|
|
69
63
|
if isinstance(x, Mapping):
|
|
70
64
|
y = cast("Mapping[Any, Any]", y)
|
|
71
65
|
x_keys = set(x)
|
|
@@ -75,14 +69,6 @@ def is_equal(
|
|
|
75
69
|
x_values = [x[i] for i in x]
|
|
76
70
|
y_values = [y[i] for i in x]
|
|
77
71
|
return is_equal(x_values, y_values, rel_tol=rel_tol, abs_tol=abs_tol)
|
|
78
|
-
if isinstance(x, AbstractSet):
|
|
79
|
-
y = cast("AbstractSet[Any]", y)
|
|
80
|
-
try:
|
|
81
|
-
x_sorted = sort_iterable(x)
|
|
82
|
-
y_sorted = sort_iterable(y)
|
|
83
|
-
except SortIterableError as error:
|
|
84
|
-
raise IsEqualError(x=error.x, y=error.y) from None
|
|
85
|
-
return is_equal(x_sorted, y_sorted, rel_tol=rel_tol, abs_tol=abs_tol)
|
|
86
72
|
if isinstance(x, Sequence):
|
|
87
73
|
y = cast("Sequence[Any]", y)
|
|
88
74
|
if len(x) != len(y):
|
|
@@ -98,6 +84,24 @@ def is_equal(
|
|
|
98
84
|
return (type(x) is type(y)) and (x == y)
|
|
99
85
|
|
|
100
86
|
|
|
87
|
+
def _is_in[T](
|
|
88
|
+
x: AbstractSet[Any],
|
|
89
|
+
y: AbstractSet[Any],
|
|
90
|
+
/,
|
|
91
|
+
*,
|
|
92
|
+
rel_tol: float | None = None,
|
|
93
|
+
abs_tol: float | None = None,
|
|
94
|
+
extra: Mapping[type[T], Callable[[T, T], bool]] | None = None,
|
|
95
|
+
) -> bool:
|
|
96
|
+
return all(
|
|
97
|
+
any(
|
|
98
|
+
is_equal(x_i, y_i, rel_tol=rel_tol, abs_tol=abs_tol, extra=extra)
|
|
99
|
+
for y_i in y
|
|
100
|
+
)
|
|
101
|
+
for x_i in x
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
101
105
|
@dataclass(kw_only=True, slots=True)
|
|
102
106
|
class IsEqualError(Exception):
|
|
103
107
|
x: Any
|
utilities/optuna.py
CHANGED
|
@@ -6,6 +6,8 @@ from typing import TYPE_CHECKING
|
|
|
6
6
|
from optuna import create_study
|
|
7
7
|
from sqlalchemy import URL
|
|
8
8
|
|
|
9
|
+
from utilities.types import Dataclass
|
|
10
|
+
|
|
9
11
|
if TYPE_CHECKING:
|
|
10
12
|
from collections.abc import Callable, Sequence
|
|
11
13
|
|
|
@@ -14,7 +16,7 @@ if TYPE_CHECKING:
|
|
|
14
16
|
from optuna.samplers import BaseSampler
|
|
15
17
|
from optuna.study import StudyDirection
|
|
16
18
|
|
|
17
|
-
from utilities.types import PathLike
|
|
19
|
+
from utilities.types import PathLike
|
|
18
20
|
|
|
19
21
|
|
|
20
22
|
def create_sqlite_study(
|
|
@@ -45,7 +47,7 @@ def create_sqlite_study(
|
|
|
45
47
|
##
|
|
46
48
|
|
|
47
49
|
|
|
48
|
-
def get_best_params(study: Study, cls: type[
|
|
50
|
+
def get_best_params[T: Dataclass](study: Study, cls: type[T], /) -> T:
|
|
49
51
|
"""Get the best params as a dataclass."""
|
|
50
52
|
return cls(**study.best_params)
|
|
51
53
|
|
|
@@ -53,10 +55,8 @@ def get_best_params(study: Study, cls: type[TDataclass], /) -> TDataclass:
|
|
|
53
55
|
##
|
|
54
56
|
|
|
55
57
|
|
|
56
|
-
def make_objective(
|
|
57
|
-
suggest_params: Callable[[Trial],
|
|
58
|
-
objective: Callable[[TDataclass], float],
|
|
59
|
-
/,
|
|
58
|
+
def make_objective[T: Dataclass](
|
|
59
|
+
suggest_params: Callable[[Trial], T], objective: Callable[[T], float], /
|
|
60
60
|
) -> Callable[[Trial], float]:
|
|
61
61
|
"""Make an objective given separate trialling & evaluating functions."""
|
|
62
62
|
|