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
@@ -0,0 +1,34 @@
1
+ Metadata-Version: 2.3
2
+ Name: dycw-utilities
3
+ Version: 0.175.17
4
+ Summary: Miscellaneous Python utilities
5
+ Author: Derek Wan
6
+ Author-email: Derek Wan <d.wan@icloud.com>
7
+ Requires-Dist: atomicwrites>=1.4.1,<1.5
8
+ Requires-Dist: typing-extensions>=4.15.0,<4.16
9
+ Requires-Dist: tzlocal>=5.3.1,<5.4
10
+ Requires-Dist: whenever>=0.9.4,<0.10
11
+ Requires-Dist: coloredlogs>=15.0.1,<15.1 ; extra == 'logging'
12
+ Requires-Dist: dycw-pytest-only>=2.1.1,<2.2 ; extra == 'test'
13
+ Requires-Dist: hypothesis>=6.148.8,<6.149 ; extra == 'test'
14
+ Requires-Dist: pytest>=9.0.2,<9.1 ; extra == 'test'
15
+ Requires-Dist: pytest-asyncio>=1.3.0,<1.4 ; extra == 'test'
16
+ Requires-Dist: pytest-cov>=7.0.0,<7.1 ; extra == 'test'
17
+ Requires-Dist: pytest-instafail>=0.5.0,<0.6 ; extra == 'test'
18
+ Requires-Dist: pytest-lazy-fixtures>=1.4.0,<1.5 ; extra == 'test'
19
+ Requires-Dist: pytest-randomly>=4.0.1,<4.1 ; extra == 'test'
20
+ Requires-Dist: pytest-regressions>=2.8.3,<2.9 ; extra == 'test'
21
+ Requires-Dist: pytest-repeat>=0.9.4,<0.10 ; extra == 'test'
22
+ Requires-Dist: pytest-rerunfailures>=16.1,<16.2 ; extra == 'test'
23
+ Requires-Dist: pytest-rng>=1.0.0,<1.1 ; extra == 'test'
24
+ Requires-Dist: pytest-timeout>=2.4.0,<2.5 ; extra == 'test'
25
+ Requires-Dist: pytest-xdist>=3.8.0,<3.9 ; extra == 'test'
26
+ Requires-Dist: testbook>=0.4.2,<0.5 ; extra == 'test'
27
+ Requires-Python: >=3.12
28
+ Provides-Extra: logging
29
+ Provides-Extra: test
30
+ Description-Content-Type: text/markdown
31
+
32
+ # `python-utilities`
33
+
34
+ Miscellaneous Python utilities
@@ -0,0 +1,103 @@
1
+ utilities/__init__.py,sha256=8_tM295sqZUhpgJO-NkFFdbuntYma_XUNSt0IM3-C_0,61
2
+ utilities/altair.py,sha256=TLfRFbG9HwG7SLXoJ-v0r-t49ZaGgTQZD82cpjVi4vs,9085
3
+ utilities/asyncio.py,sha256=aJySVxBY0gqsIYnoNmH7-1r8djKuf4vSsU69VCD08t8,16772
4
+ utilities/atomicwrites.py,sha256=tPo6r-Rypd9u99u66B9z86YBPpnLrlHtwox_8Z7T34Y,5790
5
+ utilities/atools.py,sha256=6neeCcgXxK2dlsc0xp15Za7nSucbCgFtAJepGI_-WXU,2549
6
+ utilities/cachetools.py,sha256=2S9LMHIunDYMIu8JGI7OLN04sQ7-xZGdEdP1Li0vksA,2775
7
+ utilities/click.py,sha256=ScLzBLoBp8Si5YjgB18A0IVMAR-r4sGUnVfJbAaru98,19191
8
+ utilities/concurrent.py,sha256=fHeW2SZ_TEMfFY0C8pyQI6aPlnecvx9x6SuUwBWj_JY,2853
9
+ utilities/contextlib.py,sha256=iP7R2tIm6ZsbfLD5ks6UKBYwj50e9gBI8AkpLN-chro,7476
10
+ utilities/contextvars.py,sha256=J8OhC7jqozAGYOCe2KUWysbPXNGe5JYz3HfaY_mIs08,883
11
+ utilities/cryptography.py,sha256=5PFrzsNUGHay91dFgYnDKwYprXxahrBqztmUqViRzBk,956
12
+ utilities/cvxpy.py,sha256=Rv1-fD-XYerosCavRF8Pohop2DBkU3AlFaGTfD8AEAA,13776
13
+ utilities/dataclasses.py,sha256=xbU3QN1GFy7RC6hIJRZIeUZm7YRlodrgEWmahWG6k2g,32465
14
+ utilities/docker.py,sha256=N__PKd3cnSRsXNEMHMLdLneLdyzfbr2ESkElcwrovvQ,7940
15
+ utilities/enum.py,sha256=5l6pwZD1cjSlVW4ss-zBPspWvrbrYrdtJWcg6f5_J5w,5781
16
+ utilities/errors.py,sha256=mFlDGSM0LI1jZ1pbqwLAH3ttLZ2JVIxyZLojw8tGVZU,1479
17
+ utilities/fastapi.py,sha256=TqyKvBjiMS594sXPjrz-KRTLMb3l3D3rZ1zAYV7GfOk,1454
18
+ utilities/fpdf2.py,sha256=dSiYz0FJTD2sQuxpxqFWwwIe2-p6Y7oTB9Tv0Jajit0,1866
19
+ utilities/functions.py,sha256=18Zda7nTloARdcEudH8YJ4e13xAdWShAGhPNN4w2Gyc,21498
20
+ utilities/functools.py,sha256=I00ru2gQPakZw2SHVeKIKXfTv741655s6HI0lUoE0D4,1552
21
+ utilities/getpass.py,sha256=DfN5UgMAtFCqS3dSfFHUfqIMZX2shXvwphOz_6J6f6A,103
22
+ utilities/git.py,sha256=U1RFvCTANGENgx9wVBDvllioqBQZM2ns12ivKhOsaO4,414
23
+ utilities/grp.py,sha256=1vV3gNR9dQsl1vtUtvC_2qgVdQzm7O8lLMSh56cTbeg,694
24
+ utilities/gzip.py,sha256=fkGP3KdsBfXlstodT4wtlp-PwNyUsogpbDCVVVGdsm4,781
25
+ utilities/hashlib.py,sha256=SVTgtguur0P4elppvzOBbLEjVM3Pea0eWB61yg2ilxo,309
26
+ utilities/http.py,sha256=TsavEfHlRtlLaeV21Z6KZh0qbPw-kvD1zsQdZ7Kep5Q,977
27
+ utilities/hypothesis.py,sha256=NUu30pl5kjL3tzo-m8SMRwTqLAmTWK-_Sau2NemJcQo,46773
28
+ utilities/importlib.py,sha256=SkVVtIjVC7bjJ36doXnmnmFiYe5tLbip4YAfYJj8Ycg,892
29
+ utilities/inflect.py,sha256=v7YkOWSu8NAmVghPcf4F3YBZQoJCS47_DLf9jbfWIs0,581
30
+ utilities/ipython.py,sha256=V2oMYHvEKvlNBzxDXdLvKi48oUq2SclRg5xasjaXStw,763
31
+ utilities/iterables.py,sha256=t2TsW-K3rVlS6y4_tqcc1fk9RwJV-bi7G_VwduMABK0,42558
32
+ utilities/jinja2.py,sha256=JpNHMcyMJDguX8rBN4wEz-v4En7w6WHXvYJr4Xw-F0o,4691
33
+ utilities/json.py,sha256=-WcGtSsCr9Y42wHZzAMnfvU6ihAfVftylFfRUORaDFo,2102
34
+ utilities/jupyter.py,sha256=ft5JA7fBxXKzP-L9W8f2-wbF0QeYc_2uLQNFDVk4Z-M,2917
35
+ utilities/libcst.py,sha256=ngD4wxnR3Kh-RBVmU5l5ST7cuZLhMZwyMDjHZe5mhTs,5581
36
+ utilities/lightweight_charts.py,sha256=YM3ojBvJxuCSUBu_KrhFBmaMCvRPvupKC3qkm-UVZq4,2751
37
+ utilities/logging.py,sha256=mckcX_0Q5njVgnhtIoePcDHjYjTVELw7ExutiiDnzsU,18724
38
+ utilities/math.py,sha256=cevB-YyEYAzJTWtkAr7qeeu-hbxorDI3gMznXlmNQkw,26897
39
+ utilities/memory_profiler.py,sha256=XzN56jDCa5aqXS_DxEjb_K4L6aIWh_5zyKi6OhcIxw0,853
40
+ utilities/modules.py,sha256=iuvLluJya-hvl1Q25-Jk3dLgx2Es3ck4SjJiEkAlVTs,3195
41
+ utilities/more_itertools.py,sha256=syfIPhQF_WS-YiicdGe2h5F1G-Ld12Q2XsVduL2hA40,10908
42
+ utilities/numpy.py,sha256=Xn23sA2ZbVNqwUYEgNJD3XBYH6IbCri_WkHSNhg3NkY,26122
43
+ utilities/operator.py,sha256=C3NylZWGTVWRpwYHOPVhaLgRhw0DfpS4_XQ8KfPhBLQ,3613
44
+ utilities/optuna.py,sha256=C-fhWYiXHVPo1l8QctYkFJ4DyhbSrGorzP1dJb_qvd8,1933
45
+ utilities/orjson.py,sha256=T_0SlK811ysg46d3orvIPY3JpBa4FRMpP2wlPQo7-gU,41854
46
+ utilities/os.py,sha256=kjKKSQfnRqFTTZ315iavaaGd3gGuYNoSWlxVLCJjyQs,4852
47
+ utilities/parse.py,sha256=g7Qm9eBOIeDId2tGA021CIaeF6jp1TI8rx4srdvlyoo,17937
48
+ utilities/pathlib.py,sha256=N4Ip8R9eCM-6GfvxUJ3T9oQIle2C2P52F-13BCFRdTg,9345
49
+ utilities/permissions.py,sha256=vLXlWztSVYffbrxptne7ksj6dU1HLekm4fEvS4ny_4Q,8944
50
+ utilities/pickle.py,sha256=MBT2xZCsv0pH868IXLGKnlcqNx2IRVKYNpRcqiQQqxw,653
51
+ utilities/platform.py,sha256=R3ldt2-DlI7la9ng6Rxt1CThd2lL0Ai2tC0TbabtCC0,2800
52
+ utilities/polars.py,sha256=JPzN4UqQDC7R4IXsIuXEIXRiwHSrkiSZcD8UOfwGPuE,87535
53
+ utilities/polars_ols.py,sha256=LNTFNLPuYW7fcAHymlbnams_DhitToblYvib3mhKbwI,5615
54
+ utilities/postgres.py,sha256=g3tEwTI8TdmiCbRME61ffQ0xaibdpXPu8mJOOHvjPKc,12532
55
+ utilities/pottery.py,sha256=nA0SsF9irvfC0tk68YAr08tuL9lGRSlBKihSx7Ibk84,3963
56
+ utilities/pqdm.py,sha256=idv2seRVP2f6NeSfpeEnT5A-tQezaHZKDyeu16g2-0E,3091
57
+ utilities/psutil.py,sha256=KUlu4lrUw9Zg1V7ZGetpWpGb9DB8l_SSDWGbANFNCPU,2104
58
+ utilities/pwd.py,sha256=pzlLkBfSTZsCVkMrAxEmuEoNmm-6goklfAygVmOEZqs,707
59
+ utilities/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
+ utilities/pydantic.py,sha256=z_PnYXN_UNNLQwo_XF7cr4GDcf5wicvscD6aFYVOEvA,238
61
+ utilities/pydantic_settings.py,sha256=53tQTpHFtA6UIuzHKzauZtW_bSRwL5lQnNwTWeO4Fjw,7608
62
+ utilities/pydantic_settings_sops.py,sha256=9Ou6Cx6PiYOU49vtkKqqW1Sdp_i3WlVyg8KkUUKNliM,2310
63
+ utilities/pyinstrument.py,sha256=hnXaL-4HE7wWBI5JKaPfYTpsrXe68YiuZKahHV0VJn8,841
64
+ utilities/pytest.py,sha256=9HHwYgZQe6CRF0ekHQEFH05gmoP4Ne0V54RrtUNDfi4,10524
65
+ utilities/pytest_plugins/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
66
+ utilities/pytest_plugins/pytest_randomly.py,sha256=B1qYVlExGOxTywq2r1SMi5o7btHLk2PNdY_b1p98dkE,409
67
+ utilities/pytest_plugins/pytest_regressions.py,sha256=mnHYBfdprz50UGVkVzV1bZERZN5CFfoF8YbokGxdFwU,1639
68
+ utilities/pytest_regressions.py,sha256=tJxW38u-zpoyjW1N4zogBx4V_07r-ibDInddcEUyXmc,4763
69
+ utilities/random.py,sha256=hZlH4gnAtoaofWswuJYjcygejrY8db4CzP-z_adO2Mo,4165
70
+ utilities/re.py,sha256=S4h-DLL6ScMPqjboZ_uQ1BVTJajrqV06r_81D--_HCE,4573
71
+ utilities/redis.py,sha256=gybjqKea33Jy50n4dHTS14JdquqHaJqHF2dixQljYWQ,30172
72
+ utilities/reprlib.py,sha256=ssYTcBW-TeRh3fhCJv57sopTZHF5FrPyyUg9yp5XBlo,3953
73
+ utilities/scipy.py,sha256=wZJM7fEgBAkLSYYvSmsg5ac-QuwAI0BGqHVetw1_Hb0,947
74
+ utilities/sentinel.py,sha256=A_p5jX2K0Yc5XBfoYHyBLqHsEWzE1ByOdDuzzA2pZnE,1434
75
+ utilities/shelve.py,sha256=4OzjQI6kGuUbJciqf535rwnao-_IBv66gsT6tRGiUt0,759
76
+ utilities/shutil.py,sha256=knJ7hx42FtIfGByxQZMcOSgQCDlaSony325g505ps3A,480
77
+ utilities/slack_sdk.py,sha256=76-DYtcGiUhEvl-voMamc5OjfF7Y7nCq54Bys1arqzw,2233
78
+ utilities/socket.py,sha256=K77vfREvzoVTrpYKo6MZakol0EYu2q1sWJnnZqL0So0,118
79
+ utilities/sqlalchemy.py,sha256=HQYpd7LFxdTF5WYVWYtCJeEBI71EJm7ytvCGyAH9B-U,37163
80
+ utilities/sqlalchemy_polars.py,sha256=JCGhB37raSR7fqeWV5dTsciRTMVzIdVT9YSqKT0piT0,13370
81
+ utilities/statsmodels.py,sha256=koyiBHvpMcSiBfh99wFUfSggLNx7cuAw3rwyfAhoKpQ,3410
82
+ utilities/string.py,sha256=shmBK87zZwzGyixuNuXCiUbqzfeZ9xlrFwz6JTaRvDk,582
83
+ utilities/subprocess.py,sha256=nFPIXVzXomI_Oby8PYF9HNWrsWtcSsCtgFnj_22QYlI,43753
84
+ utilities/tempfile.py,sha256=QyvIdfV4r4YZ0NeNYsg0tCijThLKa7Z32u5Kxy6ZsGo,3619
85
+ utilities/testbook.py,sha256=j1KmaVbrX9VrbeMgtPh5gk55myAsn3dyRUn7jGbPbRk,1294
86
+ utilities/text.py,sha256=7SvwcSR2l_5cOrm1samGnR4C-ZI6qyFLHLzSpO1zeHQ,13958
87
+ utilities/threading.py,sha256=GvBOp4CyhHfN90wGXZuA2VKe9fGzMaEa7oCl4f3nnPU,1009
88
+ utilities/timer.py,sha256=BGlwEVznx67scuLOUohyWJ4d5rTnwtk-IR4yLXFiNfo,2574
89
+ utilities/traceback.py,sha256=B_sc0TRUv-mGDnF-ek05nbqjmBiHr3-wvxliAqIF5hI,9608
90
+ utilities/types.py,sha256=UwxYajRnupKTCnzReaYWYqtKdpIPeSO-d97Wu4bLEq8,18878
91
+ utilities/typing.py,sha256=xuR8LxzjD-XlSftTM3TNvGVdQyV1mzpdwWdDMzWwCPE,25310
92
+ utilities/tzdata.py,sha256=fgNVj66yUbCSI_-vrRVzSD3gtf-L_8IEJEPjP_Jel5Y,266
93
+ utilities/tzlocal.py,sha256=KyCXEgCTjqGFx-389JdTuhMRUaT06U1RCMdWoED-qro,728
94
+ utilities/uuid.py,sha256=nQZs6tFX4mqtc2Ku3KqjloYCqwpTKeTj8eKwQwh3FQI,1572
95
+ utilities/version.py,sha256=ipBj5-WYY_nelp2uwFlApfWWCzTLzPwpovUi9x_OBMs,5085
96
+ utilities/warnings.py,sha256=un1LvHv70PU-LLv8RxPVmugTzDJkkGXRMZTE2-fTQHw,1771
97
+ utilities/whenever.py,sha256=F4ek0-OBWxHYrZdmoZt76N2RnNyKY5KrEHt7rqO4AQE,60183
98
+ utilities/zipfile.py,sha256=24lQc9ATcJxHXBPc_tBDiJk48pWyRrlxO2fIsFxU0A8,699
99
+ utilities/zoneinfo.py,sha256=tdIScrTB2-B-LH0ukb1HUXKooLknOfJNwHk10MuMYvA,3619
100
+ dycw_utilities-0.175.17.dist-info/WHEEL,sha256=RRVLqVugUmFOqBedBFAmA4bsgFcROUBiSUKlERi0Hcg,79
101
+ dycw_utilities-0.175.17.dist-info/entry_points.txt,sha256=cOGtKeJI0KXLSV7MJ8Dhc2G8jPgDcBDm53MVNJU4ycI,136
102
+ dycw_utilities-0.175.17.dist-info/METADATA,sha256=obLY4pbYFf5oCFvSPuNf1mXsv1VC5nCC7sGJtizR-AA,1443
103
+ dycw_utilities-0.175.17.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: uv 0.9.21
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,4 @@
1
+ [pytest11]
2
+ pytest-randomly = utilities.pytest_plugins.pytest_randomly
3
+ pytest-regressions = utilities.pytest_plugins.pytest_regressions
4
+
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.129.10"
3
+ __version__ = "0.175.17"
utilities/altair.py CHANGED
@@ -23,13 +23,12 @@ from altair import (
23
23
  )
24
24
  from altair.utils.schemapi import Undefined
25
25
 
26
+ from utilities.atomicwrites import writer
26
27
  from utilities.functions import ensure_bytes, ensure_number
27
28
  from utilities.iterables import always_iterable
28
29
  from utilities.tempfile import TemporaryDirectory
29
30
 
30
31
  if TYPE_CHECKING:
31
- from collections.abc import Sequence
32
-
33
32
  from polars import DataFrame
34
33
 
35
34
  from utilities.types import PathLike
@@ -42,7 +41,7 @@ _WIDTH = 800
42
41
 
43
42
  @dataclass(kw_only=True, slots=True)
44
43
  class _PlotDataFramesSpec:
45
- y: Sequence[str]
44
+ y: list[str]
46
45
  height: int = _HEIGHT
47
46
 
48
47
 
@@ -95,7 +94,8 @@ def plot_dataframes(
95
94
  # lines
96
95
  selection = selection_point(bind="legend", fields=[var_name], nearest=False)
97
96
  lines = [
98
- chart.mark_line(interpolate=interpolate)
97
+ chart
98
+ .mark_line(interpolate=interpolate)
99
99
  .encode(
100
100
  x=x_use,
101
101
  y=Y(value_name).scale(zero=False),
@@ -125,7 +125,8 @@ def plot_dataframes(
125
125
  else:
126
126
  tooltip_format_use = Undefined
127
127
  rules = [
128
- chart.transform_pivot(var_name, value=value_name, groupby=[x_use])
128
+ chart
129
+ .transform_pivot(var_name, value=value_name, groupby=[x_use])
129
130
  .mark_rule(color="gray")
130
131
  .encode(
131
132
  x=x_use,
@@ -144,7 +145,9 @@ def plot_dataframes(
144
145
  ]
145
146
  zoom = selection_interval(bind="scales", encodings=["x"])
146
147
  chart = (
147
- vconcat(*layers).add_params(zoom).resolve_scale(color="independent", x="shared")
148
+ vconcat_charts(*layers)
149
+ .add_params(zoom)
150
+ .resolve_scale(color="independent", x="shared")
148
151
  )
149
152
  if title is not None:
150
153
  chart = chart.properties(title=title)
@@ -228,7 +231,8 @@ def plot_intraday_dataframe(
228
231
  )
229
232
 
230
233
  data4 = (
231
- data3.group_by("_date_index")
234
+ data3
235
+ .group_by("_date_index")
232
236
  .agg(
233
237
  col(f"_{datetime}_index").min().alias(f"{datetime}_index_min"),
234
238
  (col(f"_{datetime}_index").max() + 1).alias(f"{datetime}_index_max"),
@@ -265,10 +269,8 @@ def save_chart(
265
269
  chart: _ChartLike, path: PathLike, /, *, overwrite: bool = False
266
270
  ) -> None:
267
271
  """Atomically save a chart to disk."""
268
- from utilities.atomicwrites import writer
269
-
270
272
  with writer(path, overwrite=overwrite) as temp:
271
- chart.save(str(temp), format="png")
273
+ chart.save(temp, format="png")
272
274
 
273
275
 
274
276
  ##
@@ -280,15 +282,13 @@ def save_charts_as_pdf(
280
282
  """Atomically save a chart/set of charts to disk."""
281
283
  from img2pdf import convert
282
284
 
283
- from utilities.atomicwrites import writer
284
-
285
285
  with TemporaryDirectory() as temp_dir:
286
286
  temp_paths = [temp_dir.joinpath(f"{i}.png") for i in range(len(charts))]
287
287
  for chart, temp_path in zip(charts, temp_paths, strict=True):
288
288
  save_chart(chart, temp_path)
289
289
  data = ensure_bytes(convert(*temp_paths))
290
- with writer(path, overwrite=overwrite) as temp, temp.open(mode="wb") as fh:
291
- _ = fh.write(data)
290
+ with writer(path, overwrite=overwrite) as temp:
291
+ _ = temp.write_bytes(data)
292
292
 
293
293
 
294
294
  ##