main.py 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. from typing import (
  2. TYPE_CHECKING,
  3. Callable,
  4. Tuple,
  5. Type,
  6. Union,
  7. cast,
  8. overload,
  9. )
  10. from ._utils import (
  11. to_bytes,
  12. )
  13. if TYPE_CHECKING:
  14. from typing import (
  15. SupportsIndex,
  16. )
  17. BytesLike = Union[bool, bytearray, bytes, int, str, memoryview]
  18. class HexBytes(bytes):
  19. """
  20. Thin wrapper around the python built-in :class:`bytes` class.
  21. It has these changes:
  22. 1. Accepts more initializing values: bool, bytearray, bytes, (non-negative) int,
  23. str, and memoryview
  24. 2. The representation at console (__repr__) is 0x-prefixed
  25. 3. ``to_0x_hex`` returns a 0x-prefixed hex string
  26. """
  27. def __new__(cls: Type[bytes], val: BytesLike) -> "HexBytes":
  28. bytesval = to_bytes(val)
  29. return cast(HexBytes, super().__new__(cls, bytesval)) # type: ignore # https://github.com/python/typeshed/issues/2630 # noqa: E501
  30. @overload
  31. def __getitem__(self, key: "SupportsIndex") -> int: # noqa: F811
  32. ...
  33. @overload # noqa: F811
  34. def __getitem__(self, key: slice) -> "HexBytes": # noqa: F811
  35. ...
  36. def __getitem__( # noqa: F811
  37. self, key: Union["SupportsIndex", slice]
  38. ) -> Union[int, bytes, "HexBytes"]:
  39. result = super().__getitem__(key)
  40. if hasattr(result, "hex"):
  41. return type(self)(result)
  42. else:
  43. return result
  44. def __repr__(self) -> str:
  45. return f"HexBytes({'0x' + self.hex()!r})"
  46. def to_0x_hex(self) -> str:
  47. """
  48. Convert the bytes to a 0x-prefixed hex string
  49. """
  50. return "0x" + self.hex()
  51. def __reduce__(
  52. self,
  53. ) -> Tuple[Callable[..., bytes], Tuple[Type["HexBytes"], bytes]]:
  54. """
  55. An optimized ``__reduce__`` that bypasses the input validation in
  56. ``HexBytes.__new__`` since an existing HexBytes instance has already been
  57. validated when created.
  58. """
  59. return bytes.__new__, (type(self), bytes(self))