dycw-utilities 0.166.14__py3-none-any.whl → 0.166.16__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.166.14
3
+ Version: 0.166.16
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=LHLSfs3x6K8Je1WwehDM1bM0Q8SOdoD9tS9S-GD9Vq0,61
1
+ utilities/__init__.py,sha256=FemsKd9UtEJaP-BgHzGaJoLRpH-_mhv6Y7fl8XXOKCY,61
2
2
  utilities/aeventkit.py,sha256=ddoleSwW9zdc2tjX5Ge0pMKtYwV_JMxhHYOxnWX2AGM,12609
3
3
  utilities/altair.py,sha256=nHdpWt8ZwdUwRQN970MvHd5bRWokNqzHcZQEdSHKRuE,9033
4
4
  utilities/asyncio.py,sha256=PUedzQ5deqlSECQ33sam9cRzI9TnygHz3FdOqWJWPTM,15288
@@ -46,14 +46,14 @@ utilities/parse.py,sha256=JcJn5yXKhIWXBCwgBdPsyu7Hvcuw6kyEdqvaebCaI9k,17951
46
46
  utilities/pathlib.py,sha256=X6pHmfT3hnBGysdTr73uHsNaBEgKviZhk7aGWvEXDXo,8912
47
47
  utilities/pickle.py,sha256=MBT2xZCsv0pH868IXLGKnlcqNx2IRVKYNpRcqiQQqxw,653
48
48
  utilities/platform.py,sha256=pTn7gw6N4T6LdKrf0virwarof_mze9WtoQlrGMzhGVI,2798
49
- utilities/polars.py,sha256=3C96YhfyKvmk1JiCvwTQ1mMUnsZKGlRDa6gFFlgc_uo,83235
49
+ utilities/polars.py,sha256=qsiYY9p_41fORGnc7HNkA4zhlsycK7sgD74xuigMDAc,87466
50
50
  utilities/polars_ols.py,sha256=LNTFNLPuYW7fcAHymlbnams_DhitToblYvib3mhKbwI,5615
51
51
  utilities/postgres.py,sha256=ynCTTaF-bVEOSW-KEAR-dlLh_hYjeVVjm__-4pEU8Zk,12269
52
52
  utilities/pottery.py,sha256=ggMN72Y7wx7Js8VN6eyNyodpm8TIYqZHGghkDPXIVWk,3949
53
53
  utilities/pqdm.py,sha256=idv2seRVP2f6NeSfpeEnT5A-tQezaHZKDyeu16g2-0E,3091
54
54
  utilities/psutil.py,sha256=KUlu4lrUw9Zg1V7ZGetpWpGb9DB8l_SSDWGbANFNCPU,2104
55
55
  utilities/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
- utilities/pydantic_settings.py,sha256=Kr02KzDBeohkH0n69sn7NBiJsO9W5DxNtemCm1Pp1Qg,1744
56
+ utilities/pydantic_settings.py,sha256=oUosQ7KExpXTC1PioIc4bju6C6Yj6gMZQLBpOKRL4Xc,2166
57
57
  utilities/pydantic_settings_sops.py,sha256=3RGZbRgfJjAxveMUNpdf7TNBtGuEBYZZ5_TkIxf1mNE,1194
58
58
  utilities/pyinstrument.py,sha256=hnXaL-4HE7wWBI5JKaPfYTpsrXe68YiuZKahHV0VJn8,841
59
59
  utilities/pytest.py,sha256=Pu8jmeNQq659uQmZsmFj6lb0sHMDsNN3fcd6M21J-ww,7723
@@ -91,8 +91,8 @@ utilities/zoneinfo.py,sha256=tdIScrTB2-B-LH0ukb1HUXKooLknOfJNwHk10MuMYvA,3619
91
91
  utilities/pytest_plugins/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
92
92
  utilities/pytest_plugins/pytest_randomly.py,sha256=B1qYVlExGOxTywq2r1SMi5o7btHLk2PNdY_b1p98dkE,409
93
93
  utilities/pytest_plugins/pytest_regressions.py,sha256=9v8kAXDM2ycIXJBimoiF4EgrwbUvxTycFWJiGR_GHhM,1466
94
- dycw_utilities-0.166.14.dist-info/METADATA,sha256=3P4m1rDK_LKVZkdmx4ardJpV3nshnt7hch0pA53rWyk,1702
95
- dycw_utilities-0.166.14.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
96
- dycw_utilities-0.166.14.dist-info/entry_points.txt,sha256=BOD_SoDxwsfJYOLxhrSXhHP_T7iw-HXI9f2WVkzYxvQ,135
97
- dycw_utilities-0.166.14.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
98
- dycw_utilities-0.166.14.dist-info/RECORD,,
94
+ dycw_utilities-0.166.16.dist-info/METADATA,sha256=mRIYx_yS0XbJdgF91-6wfLFf0a8T4bRtJC_v3cLoFO4,1702
95
+ dycw_utilities-0.166.16.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
96
+ dycw_utilities-0.166.16.dist-info/entry_points.txt,sha256=BOD_SoDxwsfJYOLxhrSXhHP_T7iw-HXI9f2WVkzYxvQ,135
97
+ dycw_utilities-0.166.16.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
98
+ dycw_utilities-0.166.16.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.166.14"
3
+ __version__ = "0.166.16"
utilities/polars.py CHANGED
@@ -70,6 +70,7 @@ from utilities.iterables import (
70
70
  check_supermapping,
71
71
  is_iterable_not_str,
72
72
  one,
73
+ resolve_include_and_exclude,
73
74
  )
74
75
  from utilities.json import write_formatted_json
75
76
  from utilities.math import (
@@ -1269,6 +1270,111 @@ def expr_to_series(expr: Expr, /) -> Series:
1269
1270
  ##
1270
1271
 
1271
1272
 
1273
+ @overload
1274
+ def filter_date(
1275
+ column: ExprLike = "datetime",
1276
+ /,
1277
+ *,
1278
+ time_zone: ZoneInfo | None = None,
1279
+ include: MaybeIterable[whenever.Date] | None = None,
1280
+ exclude: MaybeIterable[whenever.Date] | None = None,
1281
+ ) -> Expr: ...
1282
+ @overload
1283
+ def filter_date(
1284
+ column: Series,
1285
+ /,
1286
+ *,
1287
+ time_zone: ZoneInfo | None = None,
1288
+ include: MaybeIterable[whenever.Date] | None = None,
1289
+ exclude: MaybeIterable[whenever.Date] | None = None,
1290
+ ) -> Series: ...
1291
+ @overload
1292
+ def filter_date(
1293
+ column: IntoExprColumn = "datetime",
1294
+ /,
1295
+ *,
1296
+ time_zone: ZoneInfo | None = None,
1297
+ include: MaybeIterable[whenever.Date] | None = None,
1298
+ exclude: MaybeIterable[whenever.Date] | None = None,
1299
+ ) -> ExprOrSeries: ...
1300
+ def filter_date(
1301
+ column: IntoExprColumn = "datetime",
1302
+ /,
1303
+ *,
1304
+ time_zone: ZoneInfo | None = None,
1305
+ include: MaybeIterable[whenever.Date] | None = None,
1306
+ exclude: MaybeIterable[whenever.Date] | None = None,
1307
+ ) -> ExprOrSeries:
1308
+ """Compute the filter based on a set of dates."""
1309
+ column = ensure_expr_or_series(column)
1310
+ if time_zone is not None:
1311
+ column = column.dt.convert_time_zone(time_zone.key)
1312
+ keep = true_like(column)
1313
+ date = column.dt.date()
1314
+ include, exclude = resolve_include_and_exclude(include=include, exclude=exclude)
1315
+ if include is not None:
1316
+ keep &= date.is_in([d.py_date() for d in include])
1317
+ if exclude is not None:
1318
+ keep &= ~date.is_in([d.py_date() for d in exclude])
1319
+ return try_reify_expr(keep, column)
1320
+
1321
+
1322
+ @overload
1323
+ def filter_time(
1324
+ column: ExprLike = "datetime",
1325
+ /,
1326
+ *,
1327
+ time_zone: ZoneInfo | None = None,
1328
+ include: MaybeIterable[tuple[whenever.Time, whenever.Time]] | None = None,
1329
+ exclude: MaybeIterable[tuple[whenever.Time, whenever.Time]] | None = None,
1330
+ ) -> Expr: ...
1331
+ @overload
1332
+ def filter_time(
1333
+ column: Series,
1334
+ /,
1335
+ *,
1336
+ time_zone: ZoneInfo | None = None,
1337
+ include: MaybeIterable[tuple[whenever.Time, whenever.Time]] | None = None,
1338
+ exclude: MaybeIterable[tuple[whenever.Time, whenever.Time]] | None = None,
1339
+ ) -> Series: ...
1340
+ @overload
1341
+ def filter_time(
1342
+ column: IntoExprColumn = "datetime",
1343
+ /,
1344
+ *,
1345
+ time_zone: ZoneInfo | None = None,
1346
+ include: MaybeIterable[tuple[whenever.Time, whenever.Time]] | None = None,
1347
+ exclude: MaybeIterable[tuple[whenever.Time, whenever.Time]] | None = None,
1348
+ ) -> ExprOrSeries: ...
1349
+ def filter_time(
1350
+ column: IntoExprColumn = "datetime",
1351
+ /,
1352
+ *,
1353
+ time_zone: ZoneInfo | None = None,
1354
+ include: MaybeIterable[tuple[whenever.Time, whenever.Time]] | None = None,
1355
+ exclude: MaybeIterable[tuple[whenever.Time, whenever.Time]] | None = None,
1356
+ ) -> ExprOrSeries:
1357
+ """Compute the filter based on a set of times."""
1358
+ column = ensure_expr_or_series(column)
1359
+ if time_zone is not None:
1360
+ column = column.dt.convert_time_zone(time_zone.key)
1361
+ keep = true_like(column)
1362
+ time = column.dt.time()
1363
+ include, exclude = resolve_include_and_exclude(include=include, exclude=exclude)
1364
+ if include is not None:
1365
+ keep &= any_horizontal(
1366
+ time.is_between(s.py_time(), e.py_time()) for s, e in include
1367
+ )
1368
+ if exclude is not None:
1369
+ keep &= ~any_horizontal(
1370
+ time.is_between(s.py_time(), e.py_time()) for s, e in exclude
1371
+ )
1372
+ return try_reify_expr(keep, column)
1373
+
1374
+
1375
+ ##
1376
+
1377
+
1272
1378
  @overload
1273
1379
  def finite_ewm_mean(
1274
1380
  column: ExprLike,
@@ -2643,6 +2749,33 @@ def to_not_false(column: IntoExprColumn, /) -> ExprOrSeries:
2643
2749
  ##
2644
2750
 
2645
2751
 
2752
+ @overload
2753
+ def true_like(column: ExprLike, /) -> Expr: ...
2754
+ @overload
2755
+ def true_like(column: Series, /) -> Series: ...
2756
+ @overload
2757
+ def true_like(column: IntoExprColumn, /) -> ExprOrSeries: ...
2758
+ def true_like(column: IntoExprColumn, /) -> ExprOrSeries:
2759
+ """Compute a column of `True` values."""
2760
+ column = ensure_expr_or_series(column)
2761
+ return column.is_null() | column.is_not_null()
2762
+
2763
+
2764
+ @overload
2765
+ def false_like(column: ExprLike, /) -> Expr: ...
2766
+ @overload
2767
+ def false_like(column: Series, /) -> Series: ...
2768
+ @overload
2769
+ def false_like(column: IntoExprColumn, /) -> ExprOrSeries: ...
2770
+ def false_like(column: IntoExprColumn, /) -> ExprOrSeries:
2771
+ """Compute a column of `False` values."""
2772
+ column = ensure_expr_or_series(column)
2773
+ return column.is_null() & column.is_not_null()
2774
+
2775
+
2776
+ ##
2777
+
2778
+
2646
2779
  def try_reify_expr(
2647
2780
  expr: IntoExprColumn, /, *exprs: IntoExprColumn, **named_exprs: IntoExprColumn
2648
2781
  ) -> ExprOrSeries:
@@ -2798,6 +2931,9 @@ __all__ = [
2798
2931
  "ensure_expr_or_series",
2799
2932
  "ensure_expr_or_series_many",
2800
2933
  "expr_to_series",
2934
+ "false_like",
2935
+ "filter_date",
2936
+ "filter_time",
2801
2937
  "finite_ewm_mean",
2802
2938
  "first_true_horizontal",
2803
2939
  "get_data_type_or_series_time_zone",
@@ -2838,6 +2974,7 @@ __all__ = [
2838
2974
  "to_not_true",
2839
2975
  "to_true",
2840
2976
  "touch",
2977
+ "true_like",
2841
2978
  "try_reify_expr",
2842
2979
  "uniform",
2843
2980
  "unique_element",
@@ -7,6 +7,8 @@ from pydantic_settings import (
7
7
  JsonConfigSettingsSource,
8
8
  PydanticBaseSettingsSource,
9
9
  SettingsConfigDict,
10
+ TomlConfigSettingsSource,
11
+ YamlConfigSettingsSource,
10
12
  )
11
13
 
12
14
  from utilities.iterables import always_iterable
@@ -22,6 +24,8 @@ class CustomBaseSettings(BaseSettings):
22
24
 
23
25
  # paths
24
26
  json_files: ClassVar[MaybeIterable[PathLike]] = ()
27
+ toml_files: ClassVar[MaybeIterable[PathLike]] = ()
28
+ yaml_files: ClassVar[MaybeIterable[PathLike]] = ()
25
29
 
26
30
  # config
27
31
  model_config: ClassVar[SettingsConfigDict] = SettingsConfigDict(
@@ -51,6 +55,10 @@ class CustomBaseSettings(BaseSettings):
51
55
  yield env_settings
52
56
  for file in always_iterable(cls.json_files):
53
57
  yield JsonConfigSettingsSource(settings_cls, json_file=file)
58
+ for file in always_iterable(cls.toml_files):
59
+ yield TomlConfigSettingsSource(settings_cls, toml_file=file)
60
+ for file in always_iterable(cls.yaml_files):
61
+ yield YamlConfigSettingsSource(settings_cls, yaml_file=file)
54
62
 
55
63
 
56
64
  def load_settings[T: BaseSettings](cls: type[T], /) -> T: