1010from collections .abc import Callable , Iterable , Iterator
1111from datetime import date , datetime
1212from itertools import tee
13- from typing import (
14- Any ,
15- Literal ,
16- TypeAlias ,
17- TypeVar ,
18- cast ,
19- )
13+ from typing import Any , Literal , cast
2014
2115from .types import Json
2216from .warnings import medium
2317
24- T = TypeVar ('T' )
25- E = TypeVar ('E' , bound = Exception ) # TODO make covariant?
18+ type ResT [T , E : Exception ] = T | E
2619
27- ResT : TypeAlias = T | E
28-
29- Res : TypeAlias = ResT [T , Exception ]
20+ type Res [T ] = ResT [T , Exception ]
3021
3122ErrorPolicy = Literal ["yield" , "raise" , "drop" ]
3223
3324
34- def notnone (x : T | None ) -> T :
25+ def notnone [ T ] (x : T | None ) -> T :
3526 assert x is not None
3627 return x
3728
3829
39- def unwrap (res : Res [T ]) -> T :
30+ def unwrap [ T ] (res : Res [T ]) -> T :
4031 if isinstance (res , Exception ):
4132 raise res
4233 return res
4334
4435
45- def drop_exceptions (itr : Iterator [Res [T ]]) -> Iterator [T ]:
36+ def drop_exceptions [ T ] (itr : Iterator [Res [T ]]) -> Iterator [T ]:
4637 """Return non-errors from the iterable"""
4738 for o in itr :
4839 if isinstance (o , Exception ):
4940 continue
5041 yield o
5142
5243
53- def raise_exceptions (itr : Iterable [Res [T ]]) -> Iterator [T ]:
44+ def raise_exceptions [ T ] (itr : Iterable [Res [T ]]) -> Iterator [T ]:
5445 """Raise errors from the iterable, stops the select function"""
5546 for o in itr :
5647 if isinstance (o , Exception ):
5748 raise o
5849 yield o
5950
6051
61- def warn_exceptions (itr : Iterable [Res [T ]], warn_func : Callable [[Exception ], None ] | None = None ) -> Iterator [T ]:
52+ def warn_exceptions [ T ] (itr : Iterable [Res [T ]], warn_func : Callable [[Exception ], None ] | None = None ) -> Iterator [T ]:
6253 # if not provided, use the 'warnings' module
6354 if warn_func is None :
6455
@@ -76,12 +67,12 @@ def _warn_func(e: Exception) -> None:
7667
7768
7869# TODO deprecate in favor of Exception.add_note?
79- def echain (ex : E , cause : Exception ) -> E :
70+ def echain [ E : Exception ] (ex : E , cause : Exception ) -> E :
8071 ex .__cause__ = cause
8172 return ex
8273
8374
84- def split_errors (l : Iterable [ResT [T , E ]], ET : type [E ]) -> tuple [Iterable [T ], Iterable [E ]]:
75+ def split_errors [ T , E : Exception ] (l : Iterable [ResT [T , E ]], ET : type [E ]) -> tuple [Iterable [T ], Iterable [E ]]:
8576 # TODO would be nice to have ET=Exception default? but it causes some mypy complaints?
8677 vit , eit = tee (l )
8778 # TODO ugh, not sure if I can reconcile type checking and runtime and convince mypy that ET and E are the same type?
@@ -96,10 +87,7 @@ def split_errors(l: Iterable[ResT[T, E]], ET: type[E]) -> tuple[Iterable[T], Ite
9687 return (values , errors )
9788
9889
99- K = TypeVar ('K' )
100-
101-
102- def sort_res_by (items : Iterable [Res [T ]], key : Callable [[Any ], K ]) -> list [Res [T ]]:
90+ def sort_res_by [T , K ](items : Iterable [Res [T ]], key : Callable [[Any ], K ]) -> list [Res [T ]]:
10391 """
10492 Sort a sequence potentially interleaved with errors/entries on which the key can't be computed.
10593 The general idea is: the error sticks to the non-error entry that follows it
0 commit comments