dycw-utilities 0.167.0__py3-none-any.whl → 0.167.2__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.

Potentially problematic release.


This version of dycw-utilities might be problematic. Click here for more details.

@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dycw-utilities
3
- Version: 0.167.0
3
+ Version: 0.167.2
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
7
7
  Requires-Dist: atomicwrites<1.5,>=1.4.1
8
8
  Requires-Dist: typing-extensions<4.16,>=4.15.0
9
9
  Requires-Dist: tzlocal<5.4,>=5.3.1
10
- Requires-Dist: whenever<0.9,>=0.8.8
10
+ Requires-Dist: whenever<0.9,>=0.8.9
11
11
  Provides-Extra: logging
12
12
  Requires-Dist: coloredlogs<15.1,>=15.0.1; extra == 'logging'
13
13
  Provides-Extra: test
@@ -1,4 +1,4 @@
1
- utilities/__init__.py,sha256=dgiGa6KFuwS9sLQQWHYgtwuRxby-Kwzx_cLKTNpUlIc,60
1
+ utilities/__init__.py,sha256=TPxVHt8OYjBS7R1UkkAfJ_sezkO4fJfYhhTSaQFTd08,60
2
2
  utilities/aeventkit.py,sha256=ddoleSwW9zdc2tjX5Ge0pMKtYwV_JMxhHYOxnWX2AGM,12609
3
3
  utilities/altair.py,sha256=nHdpWt8ZwdUwRQN970MvHd5bRWokNqzHcZQEdSHKRuE,9033
4
4
  utilities/asyncio.py,sha256=60l1IwjnRGeaVphAFiwDIHyfKoZYKY-XGpptUxGiU-M,17034
@@ -69,7 +69,7 @@ utilities/sentinel.py,sha256=A_p5jX2K0Yc5XBfoYHyBLqHsEWzE1ByOdDuzzA2pZnE,1434
69
69
  utilities/shelve.py,sha256=4OzjQI6kGuUbJciqf535rwnao-_IBv66gsT6tRGiUt0,759
70
70
  utilities/slack_sdk.py,sha256=76-DYtcGiUhEvl-voMamc5OjfF7Y7nCq54Bys1arqzw,2233
71
71
  utilities/socket.py,sha256=K77vfREvzoVTrpYKo6MZakol0EYu2q1sWJnnZqL0So0,118
72
- utilities/sqlalchemy.py,sha256=X_F4Vq3t0ftgmhYdrs1DOMrI4ls5Tw_ddcW7dmhQaPY,36407
72
+ utilities/sqlalchemy.py,sha256=HQYpd7LFxdTF5WYVWYtCJeEBI71EJm7ytvCGyAH9B-U,37163
73
73
  utilities/sqlalchemy_polars.py,sha256=JCGhB37raSR7fqeWV5dTsciRTMVzIdVT9YSqKT0piT0,13370
74
74
  utilities/statsmodels.py,sha256=koyiBHvpMcSiBfh99wFUfSggLNx7cuAw3rwyfAhoKpQ,3410
75
75
  utilities/string.py,sha256=shmBK87zZwzGyixuNuXCiUbqzfeZ9xlrFwz6JTaRvDk,582
@@ -87,14 +87,14 @@ utilities/tzlocal.py,sha256=KyCXEgCTjqGFx-389JdTuhMRUaT06U1RCMdWoED-qro,728
87
87
  utilities/uuid.py,sha256=nQZs6tFX4mqtc2Ku3KqjloYCqwpTKeTj8eKwQwh3FQI,1572
88
88
  utilities/version.py,sha256=ipBj5-WYY_nelp2uwFlApfWWCzTLzPwpovUi9x_OBMs,5085
89
89
  utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
90
- utilities/whenever.py,sha256=0N5JcZU9cPyIrkTN3wqdcR86PsmIKVlLI1yU1aEbIgk,59198
90
+ utilities/whenever.py,sha256=sB-vO_7ZNmsv6Zm-J1JlpiDPuM7DuwSIwGlM7Nyauuc,60218
91
91
  utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
92
92
  utilities/zoneinfo.py,sha256=tdIScrTB2-B-LH0ukb1HUXKooLknOfJNwHk10MuMYvA,3619
93
93
  utilities/pytest_plugins/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
94
94
  utilities/pytest_plugins/pytest_randomly.py,sha256=B1qYVlExGOxTywq2r1SMi5o7btHLk2PNdY_b1p98dkE,409
95
95
  utilities/pytest_plugins/pytest_regressions.py,sha256=mnHYBfdprz50UGVkVzV1bZERZN5CFfoF8YbokGxdFwU,1639
96
- dycw_utilities-0.167.0.dist-info/METADATA,sha256=lNFPf9vIPLLTN5FD1LbxTof59uW1K-d8TriQ0JNAlUU,1698
97
- dycw_utilities-0.167.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
98
- dycw_utilities-0.167.0.dist-info/entry_points.txt,sha256=BOD_SoDxwsfJYOLxhrSXhHP_T7iw-HXI9f2WVkzYxvQ,135
99
- dycw_utilities-0.167.0.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
100
- dycw_utilities-0.167.0.dist-info/RECORD,,
96
+ dycw_utilities-0.167.2.dist-info/METADATA,sha256=r9Gt0ELmn7XKi92xRI1rt_WZz1bEDxGQom12R58FLUo,1698
97
+ dycw_utilities-0.167.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
98
+ dycw_utilities-0.167.2.dist-info/entry_points.txt,sha256=BOD_SoDxwsfJYOLxhrSXhHP_T7iw-HXI9f2WVkzYxvQ,135
99
+ dycw_utilities-0.167.2.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
100
+ dycw_utilities-0.167.2.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.167.0"
3
+ __version__ = "0.167.2"
utilities/sqlalchemy.py CHANGED
@@ -331,6 +331,20 @@ async def ensure_database_dropped(super_: URL, database: str, /) -> None:
331
331
  _ = await conn.execute(text(f"DROP DATABASE IF EXISTS {database}"))
332
332
 
333
333
 
334
+ async def ensure_database_users_disconnected(super_: URL, database: str, /) -> None:
335
+ """Ensure a databases' users are disconnected."""
336
+ engine = create_async_engine(super_, isolation_level="AUTOCOMMIT")
337
+ match dialect := _get_dialect(engine):
338
+ case "postgresql": # skipif-ci-and-not-linux
339
+ query = f"SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = {database!r} AND pid <> pg_backend_pid()" # noqa: S608
340
+ case "mssql" | "mysql" | "oracle" | "sqlite": # pragma: no cover
341
+ raise NotImplementedError(dialect)
342
+ case never:
343
+ assert_never(never)
344
+ async with engine.begin() as conn:
345
+ _ = await conn.execute(text(query))
346
+
347
+
334
348
  ##
335
349
 
336
350
 
@@ -1166,6 +1180,7 @@ __all__ = [
1166
1180
  "create_engine",
1167
1181
  "ensure_database_created",
1168
1182
  "ensure_database_dropped",
1183
+ "ensure_database_users_disconnected",
1169
1184
  "ensure_tables_created",
1170
1185
  "ensure_tables_dropped",
1171
1186
  "enum_name",
utilities/whenever.py CHANGED
@@ -433,6 +433,36 @@ TODAY_LOCAL = get_today_local()
433
433
  ##
434
434
 
435
435
 
436
+ def is_weekend(
437
+ date_time: ZonedDateTime,
438
+ /,
439
+ *,
440
+ start: tuple[Weekday, Time] = (Weekday.SATURDAY, Time.MIN),
441
+ end: tuple[Weekday, Time] = (Weekday.SUNDAY, Time.MAX),
442
+ ) -> bool:
443
+ """Check if a datetime is in the weekend."""
444
+ weekday, time = date_time.date().day_of_week(), date_time.time()
445
+ start_weekday, start_time = start
446
+ end_weekday, end_time = end
447
+ if start_weekday.value == end_weekday.value:
448
+ return start_time <= time <= end_time
449
+ if start_weekday.value < end_weekday.value:
450
+ return (
451
+ ((weekday == start_weekday) and (time >= start_time))
452
+ or (start_weekday.value < weekday.value < end_weekday.value)
453
+ or ((weekday == end_weekday) and (time <= end_time))
454
+ )
455
+ return (
456
+ ((weekday == start_weekday) and (time >= start_time))
457
+ or (weekday.value > start_weekday.value)
458
+ or (weekday.value < end_weekday.value)
459
+ or ((weekday == end_weekday) and (time <= end_time))
460
+ )
461
+
462
+
463
+ ##
464
+
465
+
436
466
  def mean_datetime(
437
467
  datetimes: Iterable[ZonedDateTime],
438
468
  /,
@@ -2033,6 +2063,7 @@ __all__ = [
2033
2063
  "get_time_local",
2034
2064
  "get_today",
2035
2065
  "get_today_local",
2066
+ "is_weekend",
2036
2067
  "mean_datetime",
2037
2068
  "min_max_date",
2038
2069
  "round_date_or_date_time",