1from __future__ import annotations
2
3import typing
4from types import TracebackType
5
6
7def to_bytes(
8 x: str | bytes, encoding: str | None = None, errors: str | None = None
9) -> bytes:
10 if isinstance(x, bytes):
11 return x
12 elif not isinstance(x, str):
13 raise TypeError(f"not expecting type {type(x).__name__}")
14 if encoding or errors:
15 return x.encode(encoding or "utf-8", errors=errors or "strict")
16 return x.encode()
17
18
19def to_str(
20 x: str | bytes, encoding: str | None = None, errors: str | None = None
21) -> str:
22 if isinstance(x, str):
23 return x
24 elif not isinstance(x, bytes):
25 raise TypeError(f"not expecting type {type(x).__name__}")
26 if encoding or errors:
27 return x.decode(encoding or "utf-8", errors=errors or "strict")
28 return x.decode()
29
30
31def reraise(
32 tp: type[BaseException] | None,
33 value: BaseException,
34 tb: TracebackType | None = None,
35) -> typing.NoReturn:
36 try:
37 if value.__traceback__ is not tb:
38 raise value.with_traceback(tb)
39 raise value
40 finally:
41 value = None # type: ignore[assignment]
42 tb = None