from typing import ( TYPE_CHECKING, Callable, Tuple, Type, Union, cast, overload, ) from ._utils import ( to_bytes, ) if TYPE_CHECKING: from typing import ( SupportsIndex, ) BytesLike = Union[bool, bytearray, bytes, int, str, memoryview] class HexBytes(bytes): """ Thin wrapper around the python built-in :class:`bytes` class. It has these changes: 1. Accepts more initializing values: bool, bytearray, bytes, (non-negative) int, str, and memoryview 2. The representation at console (__repr__) is 0x-prefixed 3. ``to_0x_hex`` returns a 0x-prefixed hex string """ def __new__(cls: Type[bytes], val: BytesLike) -> "HexBytes": bytesval = to_bytes(val) return cast(HexBytes, super().__new__(cls, bytesval)) # type: ignore # https://github.com/python/typeshed/issues/2630 # noqa: E501 @overload def __getitem__(self, key: "SupportsIndex") -> int: # noqa: F811 ... @overload # noqa: F811 def __getitem__(self, key: slice) -> "HexBytes": # noqa: F811 ... def __getitem__( # noqa: F811 self, key: Union["SupportsIndex", slice] ) -> Union[int, bytes, "HexBytes"]: result = super().__getitem__(key) if hasattr(result, "hex"): return type(self)(result) else: return result def __repr__(self) -> str: return f"HexBytes({'0x' + self.hex()!r})" def to_0x_hex(self) -> str: """ Convert the bytes to a 0x-prefixed hex string """ return "0x" + self.hex() def __reduce__( self, ) -> Tuple[Callable[..., bytes], Tuple[Type["HexBytes"], bytes]]: """ An optimized ``__reduce__`` that bypasses the input validation in ``HexBytes.__new__`` since an existing HexBytes instance has already been validated when created. """ return bytes.__new__, (type(self), bytes(self))