dycw-utilities 0.166.13__py3-none-any.whl → 0.166.15__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.13
3
+ Version: 0.166.15
4
4
  Author-email: Derek Wan <d.wan@icloud.com>
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
@@ -20,7 +20,7 @@ Requires-Dist: pytest-lazy-fixtures<1.4,>=1.3.4; extra == 'test'
20
20
  Requires-Dist: pytest-randomly<3.17,>=3.16.0; extra == 'test'
21
21
  Requires-Dist: pytest-regressions<2.9,>=2.8.2; extra == 'test'
22
22
  Requires-Dist: pytest-repeat<0.10,>=0.9.4; extra == 'test'
23
- Requires-Dist: pytest-rerunfailures<16,>=15.1; extra == 'test'
23
+ Requires-Dist: pytest-rerunfailures<16.1,>=16.0.1; extra == 'test'
24
24
  Requires-Dist: pytest-rng<1.1,>=1.0.0; extra == 'test'
25
25
  Requires-Dist: pytest-timeout<2.5,>=2.4.0; extra == 'test'
26
26
  Requires-Dist: pytest-xdist<3.9,>=3.8.0; extra == 'test'
@@ -1,11 +1,11 @@
1
- utilities/__init__.py,sha256=eooegoV4CjSVy6iMSaAq_9yciReXtKRHHsnCb_5tG8g,61
1
+ utilities/__init__.py,sha256=jOtUA_AbgiE81h3dMxZMFbVi1ROzPoQzJX8qlRlwxKs,61
2
2
  utilities/aeventkit.py,sha256=ddoleSwW9zdc2tjX5Ge0pMKtYwV_JMxhHYOxnWX2AGM,12609
3
- utilities/altair.py,sha256=92E2lCdyHY4Zb-vCw6rEJIsWdKipuu-Tu2ab1ufUfAk,9079
3
+ utilities/altair.py,sha256=nHdpWt8ZwdUwRQN970MvHd5bRWokNqzHcZQEdSHKRuE,9033
4
4
  utilities/asyncio.py,sha256=PUedzQ5deqlSECQ33sam9cRzI9TnygHz3FdOqWJWPTM,15288
5
5
  utilities/atomicwrites.py,sha256=tPo6r-Rypd9u99u66B9z86YBPpnLrlHtwox_8Z7T34Y,5790
6
6
  utilities/atools.py,sha256=6neeCcgXxK2dlsc0xp15Za7nSucbCgFtAJepGI_-WXU,2549
7
7
  utilities/cachetools.py,sha256=v1-9sXHLdOLiwmkq6NB0OUbxeKBuVVN6wmAWefWoaHI,2744
8
- utilities/click.py,sha256=N-6lnXPYwiiciEdiwQbIp0C9UqwpWpBPmA2jMl_lmGY,17471
8
+ utilities/click.py,sha256=RPdpxVt3cE2Ahbw0-ziMhvnsR05YSKNJxnmmjRD2zWQ,17449
9
9
  utilities/concurrent.py,sha256=fHeW2SZ_TEMfFY0C8pyQI6aPlnecvx9x6SuUwBWj_JY,2853
10
10
  utilities/contextlib.py,sha256=iP7R2tIm6ZsbfLD5ks6UKBYwj50e9gBI8AkpLN-chro,7476
11
11
  utilities/contextvars.py,sha256=J8OhC7jqozAGYOCe2KUWysbPXNGe5JYz3HfaY_mIs08,883
@@ -23,14 +23,14 @@ utilities/git.py,sha256=U1RFvCTANGENgx9wVBDvllioqBQZM2ns12ivKhOsaO4,414
23
23
  utilities/gzip.py,sha256=fkGP3KdsBfXlstodT4wtlp-PwNyUsogpbDCVVVGdsm4,781
24
24
  utilities/hashlib.py,sha256=SVTgtguur0P4elppvzOBbLEjVM3Pea0eWB61yg2ilxo,309
25
25
  utilities/http.py,sha256=TsavEfHlRtlLaeV21Z6KZh0qbPw-kvD1zsQdZ7Kep5Q,977
26
- utilities/hypothesis.py,sha256=lkgPbGjTMTxSXSsZUwmkTpAUex441aWUy_V_l5LwPfM,45528
26
+ utilities/hypothesis.py,sha256=VdVjsFiTl4E6JKHW764iseuySw8JUTsIvotW2qBQfak,45533
27
27
  utilities/importlib.py,sha256=mV1xT_O_zt_GnZZ36tl3xOmMaN_3jErDWY54fX39F6Y,429
28
28
  utilities/inflect.py,sha256=v7YkOWSu8NAmVghPcf4F3YBZQoJCS47_DLf9jbfWIs0,581
29
29
  utilities/ipython.py,sha256=V2oMYHvEKvlNBzxDXdLvKi48oUq2SclRg5xasjaXStw,763
30
30
  utilities/iterables.py,sha256=8_dljtugLjxL8GCO_udMoH5uldvxdAmsN6aZ3EdnAiA,42564
31
31
  utilities/json.py,sha256=-WcGtSsCr9Y42wHZzAMnfvU6ihAfVftylFfRUORaDFo,2102
32
32
  utilities/jupyter.py,sha256=ft5JA7fBxXKzP-L9W8f2-wbF0QeYc_2uLQNFDVk4Z-M,2917
33
- utilities/libcst.py,sha256=TKgKN4bNmtBNEE-TUfhTyd1BrTncfsl_7tTuhpesGYY,5585
33
+ utilities/libcst.py,sha256=ngD4wxnR3Kh-RBVmU5l5ST7cuZLhMZwyMDjHZe5mhTs,5581
34
34
  utilities/lightweight_charts.py,sha256=YM3ojBvJxuCSUBu_KrhFBmaMCvRPvupKC3qkm-UVZq4,2751
35
35
  utilities/logging.py,sha256=W3d8Vby0mmqGWvTNlGtcfrmORDTt7abCuqjkIyCPIg8,18914
36
36
  utilities/math.py,sha256=cevB-YyEYAzJTWtkAr7qeeu-hbxorDI3gMznXlmNQkw,26897
@@ -46,17 +46,17 @@ 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=FehlIHgHP-kvicBPSE6o-tswqUpRysA6epmkPrgHkGE,83239
49
+ utilities/polars.py,sha256=3C96YhfyKvmk1JiCvwTQ1mMUnsZKGlRDa6gFFlgc_uo,83235
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
- utilities/pytest.py,sha256=M-Om6b3hpF9W_bEB7UFY2IzBCubSxzVQleGrgRXHtxY,7741
59
+ utilities/pytest.py,sha256=Pu8jmeNQq659uQmZsmFj6lb0sHMDsNN3fcd6M21J-ww,7723
60
60
  utilities/pytest_regressions.py,sha256=ocjHTtfOeiGfQAKIei8pKNd61sxN9dawrJJ9gPt2wzA,4097
61
61
  utilities/random.py,sha256=hZlH4gnAtoaofWswuJYjcygejrY8db4CzP-z_adO2Mo,4165
62
62
  utilities/re.py,sha256=S4h-DLL6ScMPqjboZ_uQ1BVTJajrqV06r_81D--_HCE,4573
@@ -67,16 +67,16 @@ utilities/sentinel.py,sha256=A_p5jX2K0Yc5XBfoYHyBLqHsEWzE1ByOdDuzzA2pZnE,1434
67
67
  utilities/shelve.py,sha256=4OzjQI6kGuUbJciqf535rwnao-_IBv66gsT6tRGiUt0,759
68
68
  utilities/slack_sdk.py,sha256=76-DYtcGiUhEvl-voMamc5OjfF7Y7nCq54Bys1arqzw,2233
69
69
  utilities/socket.py,sha256=K77vfREvzoVTrpYKo6MZakol0EYu2q1sWJnnZqL0So0,118
70
- utilities/sqlalchemy.py,sha256=gCd7rBn7mDt1ZepxMtW4j0QSUo-zwCC3VvzH8P0LcZI,36411
70
+ utilities/sqlalchemy.py,sha256=X_F4Vq3t0ftgmhYdrs1DOMrI4ls5Tw_ddcW7dmhQaPY,36407
71
71
  utilities/sqlalchemy_polars.py,sha256=JCGhB37raSR7fqeWV5dTsciRTMVzIdVT9YSqKT0piT0,13370
72
72
  utilities/statsmodels.py,sha256=koyiBHvpMcSiBfh99wFUfSggLNx7cuAw3rwyfAhoKpQ,3410
73
73
  utilities/string.py,sha256=shmBK87zZwzGyixuNuXCiUbqzfeZ9xlrFwz6JTaRvDk,582
74
74
  utilities/tempfile.py,sha256=HxB2BF28CcecDJLQ3Bx2Ej-Pb6RJc6W9ngSpB9CnP4k,2018
75
75
  utilities/testbook.py,sha256=j1KmaVbrX9VrbeMgtPh5gk55myAsn3dyRUn7jGbPbRk,1294
76
- utilities/text.py,sha256=NVPywVHGnHzyjs1N1U8J4YIqKCU3v-794y6c3px1wYo,13667
76
+ utilities/text.py,sha256=GkjXhJk1UbKEoh2VnMR6UfmunuCwCL4pa-2AmgKE2pU,13666
77
77
  utilities/threading.py,sha256=GvBOp4CyhHfN90wGXZuA2VKe9fGzMaEa7oCl4f3nnPU,1009
78
78
  utilities/timer.py,sha256=oXfTii6ymu57niP0BDGZjFD55LEHi2a19kqZKiTgaFQ,2588
79
- utilities/traceback.py,sha256=b1nSvlyrGmI1MyZLkkoLVET3DQBSGt9qqIlAAQbyjEw,9629
79
+ utilities/traceback.py,sha256=-tgTUnryG7Bu2tOXjURIIpC4ohIVBzVAxIj6Kf3xxCM,9615
80
80
  utilities/typed_settings.py,sha256=bCGybctbjNDEbUBCvQFhKitRFrk9ixImpvbIpshgbtA,4644
81
81
  utilities/types.py,sha256=IlRrCtPdLkGYVfpe-QIg2qNUgBr8OJNN7BhTKxnhh-M,18817
82
82
  utilities/typing.py,sha256=QYoCIc71e_u5W-kBeiNzrD-GXxpLtMOGc9PqgZjMXeE,25274
@@ -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.13.dist-info/METADATA,sha256=YOLnbQfQ3FBhIuG0xA_6uNEFL6laryoLaMgJTKSpILA,1698
95
- dycw_utilities-0.166.13.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
96
- dycw_utilities-0.166.13.dist-info/entry_points.txt,sha256=BOD_SoDxwsfJYOLxhrSXhHP_T7iw-HXI9f2WVkzYxvQ,135
97
- dycw_utilities-0.166.13.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
98
- dycw_utilities-0.166.13.dist-info/RECORD,,
94
+ dycw_utilities-0.166.15.dist-info/METADATA,sha256=tZarKfDKJCz0QAcuEaTEObHvD4g5MTe-eNSIe_DbDkM,1702
95
+ dycw_utilities-0.166.15.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
96
+ dycw_utilities-0.166.15.dist-info/entry_points.txt,sha256=BOD_SoDxwsfJYOLxhrSXhHP_T7iw-HXI9f2WVkzYxvQ,135
97
+ dycw_utilities-0.166.15.dist-info/licenses/LICENSE,sha256=gppZp16M6nSVpBbUBrNL6JuYfvKwZiKgV7XoKKsHzqo,1066
98
+ dycw_utilities-0.166.15.dist-info/RECORD,,
utilities/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from __future__ import annotations
2
2
 
3
- __version__ = "0.166.13"
3
+ __version__ = "0.166.15"
utilities/altair.py CHANGED
@@ -29,8 +29,6 @@ from utilities.iterables import always_iterable
29
29
  from utilities.tempfile import TemporaryDirectory
30
30
 
31
31
  if TYPE_CHECKING:
32
- from collections.abc import Sequence
33
-
34
32
  from polars import DataFrame
35
33
 
36
34
  from utilities.types import PathLike
@@ -43,7 +41,7 @@ _WIDTH = 800
43
41
 
44
42
  @dataclass(kw_only=True, slots=True)
45
43
  class _PlotDataFramesSpec:
46
- y: Sequence[str]
44
+ y: list[str]
47
45
  height: int = _HEIGHT
48
46
 
49
47
 
utilities/click.py CHANGED
@@ -17,7 +17,7 @@ from utilities.parse import ParseObjectError, parse_object
17
17
  from utilities.text import split_str
18
18
 
19
19
  if TYPE_CHECKING:
20
- from collections.abc import Iterable, Sequence
20
+ from collections.abc import Iterable
21
21
 
22
22
  from utilities.types import (
23
23
  DateDeltaLike,
@@ -38,7 +38,7 @@ if TYPE_CHECKING:
38
38
 
39
39
 
40
40
  class _HelpOptionNames(TypedDict):
41
- help_option_names: Sequence[str]
41
+ help_option_names: list[str]
42
42
 
43
43
 
44
44
  class _ContextSettings(TypedDict):
@@ -469,7 +469,7 @@ class FrozenSetChoices(FrozenSetParameter[Choice, str]):
469
469
  @override
470
470
  def __init__(
471
471
  self,
472
- choices: Sequence[str],
472
+ choices: list[str],
473
473
  /,
474
474
  *,
475
475
  case_sensitive: bool = False,
@@ -554,7 +554,7 @@ class ListChoices(ListParameter[Choice, str]):
554
554
  @override
555
555
  def __init__(
556
556
  self,
557
- choices: Sequence[str],
557
+ choices: list[str],
558
558
  /,
559
559
  *,
560
560
  case_sensitive: bool = False,
utilities/hypothesis.py CHANGED
@@ -847,13 +847,9 @@ def paths(
847
847
  ) -> Path:
848
848
  """Strategy for generating `Path`s."""
849
849
  min_depth_, max_depth_ = [draw2(draw, d) for d in [min_depth, max_depth]]
850
- parts = draw(
851
- lists(
852
- _path_parts(),
853
- min_size=0 if min_depth_ is None else min_depth_,
854
- max_size=max_depth_,
855
- )
856
- )
850
+ min_depth_ = max_nullable([min_depth_, 0])
851
+ max_depth_ = min_nullable([max_depth_, 10])
852
+ parts = draw(lists(_path_parts(), min_size=min_depth_, max_size=max_depth_))
857
853
  return Path(*parts)
858
854
 
859
855
 
utilities/libcst.py CHANGED
@@ -150,7 +150,7 @@ def split_dotted_str(dotted: str, /) -> Name | Attribute:
150
150
 
151
151
  def join_dotted_str(name_or_attr: Name | Attribute, /) -> str:
152
152
  """Join a dotted from from a name/attribute."""
153
- parts: Sequence[str] = []
153
+ parts: list[str] = []
154
154
  curr: BaseExpression | Name | Attribute = name_or_attr
155
155
  while True:
156
156
  match curr:
utilities/polars.py CHANGED
@@ -564,7 +564,7 @@ def _check_polars_dataframe_columns(df: DataFrame, columns: Iterable[str], /) ->
564
564
 
565
565
  @dataclass(kw_only=True, slots=True)
566
566
  class _CheckPolarsDataFrameColumnsError(CheckPolarsDataFrameError):
567
- columns: Sequence[str]
567
+ columns: list[str]
568
568
 
569
569
  @override
570
570
  def __str__(self) -> str:
@@ -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:
utilities/pytest.py CHANGED
@@ -26,7 +26,7 @@ from utilities.types import MaybeCoro
26
26
  from utilities.whenever import SECOND, get_now_local
27
27
 
28
28
  if TYPE_CHECKING:
29
- from collections.abc import Callable, Iterable, Sequence
29
+ from collections.abc import Callable, Iterable
30
30
 
31
31
  from utilities.types import Coro, Delta, PathLike
32
32
 
@@ -52,7 +52,7 @@ else:
52
52
  skipif_not_linux = mark.skipif(IS_NOT_LINUX, reason="Skipped for non-Linux")
53
53
 
54
54
 
55
- def add_pytest_addoption(parser: Parser, options: Sequence[str], /) -> None:
55
+ def add_pytest_addoption(parser: Parser, options: list[str], /) -> None:
56
56
  """Add the `--slow`, etc options to pytest.
57
57
 
58
58
  Usage:
@@ -73,7 +73,7 @@ def add_pytest_addoption(parser: Parser, options: Sequence[str], /) -> None:
73
73
 
74
74
 
75
75
  def add_pytest_collection_modifyitems(
76
- config: Config, items: Iterable[Function], options: Sequence[str], /
76
+ config: Config, items: Iterable[Function], options: list[str], /
77
77
  ) -> None:
78
78
  """Add the @mark.skips as necessary.
79
79
 
utilities/sqlalchemy.py CHANGED
@@ -1073,7 +1073,7 @@ def _map_mapping_to_table(
1073
1073
  @dataclass(kw_only=True, slots=True)
1074
1074
  class _MapMappingToTableError(Exception):
1075
1075
  mapping: StrMapping
1076
- columns: Sequence[str]
1076
+ columns: list[str]
1077
1077
 
1078
1078
 
1079
1079
  @dataclass(kw_only=True, slots=True)
utilities/text.py CHANGED
@@ -276,7 +276,7 @@ def split_str(
276
276
  separator: str = DEFAULT_SEPARATOR,
277
277
  brackets: Iterable[tuple[str, str]] | None = None,
278
278
  n: int | None = None,
279
- ) -> Sequence[str]: ...
279
+ ) -> tuple[str, ...]: ...
280
280
  def split_str(
281
281
  text: str,
282
282
  /,
@@ -284,7 +284,7 @@ def split_str(
284
284
  separator: str = DEFAULT_SEPARATOR,
285
285
  brackets: Iterable[tuple[str, str]] | None = None,
286
286
  n: int | None = None,
287
- ) -> Sequence[str]:
287
+ ) -> tuple[str, ...]:
288
288
  """Split a string, with a special provision for the empty string."""
289
289
  if text == "":
290
290
  texts = []
@@ -295,7 +295,7 @@ def split_str(
295
295
  else:
296
296
  texts = _split_str_brackets(text, brackets, separator=separator)
297
297
  if n is None:
298
- return texts
298
+ return tuple(texts)
299
299
  if len(texts) != n:
300
300
  raise _SplitStrCountError(text=text, n=n, texts=texts)
301
301
  return tuple(texts)
@@ -307,7 +307,7 @@ def _split_str_brackets(
307
307
  /,
308
308
  *,
309
309
  separator: str = DEFAULT_SEPARATOR,
310
- ) -> Sequence[str]:
310
+ ) -> list[str]:
311
311
  brackets = list(brackets)
312
312
  opens, closes = transpose(brackets)
313
313
  close_to_open = {close: open_ for open_, close in brackets}
@@ -315,7 +315,7 @@ def _split_str_brackets(
315
315
  escapes = map(escape, chain(chain.from_iterable(brackets), [separator]))
316
316
  pattern = re.compile("|".join(escapes))
317
317
 
318
- results: Sequence[str] = []
318
+ results: list[str] = []
319
319
  stack: deque[tuple[str, int]] = deque()
320
320
  last = 0
321
321
 
@@ -357,7 +357,7 @@ class SplitStrError(Exception):
357
357
  @dataclass(kw_only=True, slots=True)
358
358
  class _SplitStrCountError(SplitStrError):
359
359
  n: int
360
- texts: Sequence[str]
360
+ texts: list[str]
361
361
 
362
362
  @override
363
363
  def __str__(self) -> str:
utilities/traceback.py CHANGED
@@ -37,7 +37,7 @@ from utilities.whenever import (
37
37
  )
38
38
 
39
39
  if TYPE_CHECKING:
40
- from collections.abc import Callable, Iterator, Sequence
40
+ from collections.abc import Callable, Iterator
41
41
  from traceback import FrameSummary
42
42
  from types import TracebackType
43
43
 
@@ -70,7 +70,7 @@ def format_exception_stack(
70
70
  expand_all: bool = RICH_EXPAND_ALL,
71
71
  ) -> str:
72
72
  """Format an exception stack."""
73
- lines: Sequence[str] = []
73
+ lines: list[str] = []
74
74
  if header:
75
75
  lines.extend(_yield_header_lines(start=start, version=version))
76
76
  lines.extend(