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.
Files changed (103) hide show
  1. dycw_utilities-0.175.17.dist-info/METADATA +34 -0
  2. dycw_utilities-0.175.17.dist-info/RECORD +103 -0
  3. dycw_utilities-0.175.17.dist-info/WHEEL +4 -0
  4. dycw_utilities-0.175.17.dist-info/entry_points.txt +4 -0
  5. utilities/__init__.py +1 -1
  6. utilities/altair.py +14 -14
  7. utilities/asyncio.py +350 -819
  8. utilities/atomicwrites.py +18 -6
  9. utilities/atools.py +77 -22
  10. utilities/cachetools.py +24 -29
  11. utilities/click.py +393 -237
  12. utilities/concurrent.py +8 -11
  13. utilities/contextlib.py +216 -17
  14. utilities/contextvars.py +20 -1
  15. utilities/cryptography.py +3 -3
  16. utilities/dataclasses.py +83 -118
  17. utilities/docker.py +293 -0
  18. utilities/enum.py +26 -23
  19. utilities/errors.py +17 -3
  20. utilities/fastapi.py +29 -65
  21. utilities/fpdf2.py +3 -3
  22. utilities/functions.py +169 -416
  23. utilities/functools.py +18 -19
  24. utilities/git.py +9 -30
  25. utilities/grp.py +28 -0
  26. utilities/gzip.py +31 -0
  27. utilities/http.py +3 -2
  28. utilities/hypothesis.py +738 -589
  29. utilities/importlib.py +17 -1
  30. utilities/inflect.py +25 -0
  31. utilities/iterables.py +194 -262
  32. utilities/jinja2.py +148 -0
  33. utilities/json.py +70 -0
  34. utilities/libcst.py +38 -17
  35. utilities/lightweight_charts.py +5 -9
  36. utilities/logging.py +345 -543
  37. utilities/math.py +18 -13
  38. utilities/memory_profiler.py +11 -15
  39. utilities/more_itertools.py +200 -131
  40. utilities/operator.py +33 -29
  41. utilities/optuna.py +6 -6
  42. utilities/orjson.py +272 -137
  43. utilities/os.py +61 -4
  44. utilities/parse.py +59 -61
  45. utilities/pathlib.py +281 -40
  46. utilities/permissions.py +298 -0
  47. utilities/pickle.py +2 -2
  48. utilities/platform.py +24 -5
  49. utilities/polars.py +1214 -430
  50. utilities/polars_ols.py +1 -1
  51. utilities/postgres.py +408 -0
  52. utilities/pottery.py +113 -26
  53. utilities/pqdm.py +10 -11
  54. utilities/psutil.py +6 -57
  55. utilities/pwd.py +28 -0
  56. utilities/pydantic.py +4 -54
  57. utilities/pydantic_settings.py +240 -0
  58. utilities/pydantic_settings_sops.py +76 -0
  59. utilities/pyinstrument.py +8 -10
  60. utilities/pytest.py +227 -121
  61. utilities/pytest_plugins/__init__.py +1 -0
  62. utilities/pytest_plugins/pytest_randomly.py +23 -0
  63. utilities/pytest_plugins/pytest_regressions.py +56 -0
  64. utilities/pytest_regressions.py +26 -46
  65. utilities/random.py +13 -9
  66. utilities/re.py +58 -28
  67. utilities/redis.py +401 -550
  68. utilities/scipy.py +1 -1
  69. utilities/sentinel.py +10 -0
  70. utilities/shelve.py +4 -1
  71. utilities/shutil.py +25 -0
  72. utilities/slack_sdk.py +36 -106
  73. utilities/sqlalchemy.py +502 -473
  74. utilities/sqlalchemy_polars.py +38 -94
  75. utilities/string.py +2 -3
  76. utilities/subprocess.py +1572 -0
  77. utilities/tempfile.py +86 -4
  78. utilities/testbook.py +50 -0
  79. utilities/text.py +165 -42
  80. utilities/timer.py +37 -65
  81. utilities/traceback.py +158 -929
  82. utilities/types.py +146 -116
  83. utilities/typing.py +531 -71
  84. utilities/tzdata.py +1 -53
  85. utilities/tzlocal.py +6 -23
  86. utilities/uuid.py +43 -5
  87. utilities/version.py +27 -26
  88. utilities/whenever.py +1776 -386
  89. utilities/zoneinfo.py +84 -22
  90. dycw_utilities-0.129.10.dist-info/METADATA +0 -241
  91. dycw_utilities-0.129.10.dist-info/RECORD +0 -96
  92. dycw_utilities-0.129.10.dist-info/WHEEL +0 -4
  93. dycw_utilities-0.129.10.dist-info/licenses/LICENSE +0 -21
  94. utilities/datetime.py +0 -1409
  95. utilities/eventkit.py +0 -402
  96. utilities/loguru.py +0 -144
  97. utilities/luigi.py +0 -228
  98. utilities/period.py +0 -324
  99. utilities/pyrsistent.py +0 -89
  100. utilities/python_dotenv.py +0 -105
  101. utilities/streamlit.py +0 -105
  102. utilities/sys.py +0 -87
  103. 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, TypeVar, cast, override
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, DateOrDateTime, Number
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[_T], Callable[[_T, _T], bool]] | None = None,
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("_T", x)
44
- y = cast("_T", y)
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, TDataclass
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[TDataclass], /) -> TDataclass:
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], TDataclass],
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