There is a simple function.
What should I do? (Sorry for my poor english.)
def func(a: AnyStr, *b: AnyStr) -> Tuple[Optional[AnyStr], AnyStr]: for _b in b: if a.startswith(_b): return (_b, a.removeprefix(_b)) return (None, a)Then, I added the ability to convert AValue instances (_b) to str or bytes for some reason.
@dataclass class AValue: value: str val = AValue("abcd") def func(a: AnyStr, *b: AnyStr | AValue) -> Tuple[Optional[AnyStr | AValue], AnyStr]: for _b in b: if isinstance(_b, AValue): # ..... some code convert _b into AnyStr (_tb) that match a else: _tb = _b if a.startswith(_tb): return (_b, a.removeprefix(_tb)) return (None, a)However, type annotations are not perfect. If I write
result = func('abcd', 'a', 'b')
, type checkers still think result[0] maybe Optional[AnyStr | AValue]
. How to annotate result[0] that type checkers will think it's Optional[AnyStr]
if there is only AnyStr in b?a, _ = func("Abcd", AValue("A"), "b", b"c") reveal_type(a) # Optional[AValue | str] b, _ = func("Abcd", "A", b"b") reveal_type(b) # Optional[str]I tried this:
T = TypeVar('T', bytes, str, AValue) def func(a: AnyStr, *b: T) -> Tuple[Optional[T], AnyStr]: for _b in b: if isinstance(_b, AValue): # ..... some code convert _b into AnyStr (_tb) that match a else: _tb = _b if a.startswith(_tb): return (_b, a.removeprefix(_tb)) return (None, a)It's not perfect that type checkers will think
func("abcd", AValue("efgh"), b"ijkl")
(b"ijkl"'s type should be same as "abcd") is ok.What should I do? (Sorry for my poor english.)