Skip to content

Commit

Permalink
move prepend of 0x to HexBytes.__repr__ to allow HexBytes.hex output …
Browse files Browse the repository at this point in the history
…to match parent class bytes.hex
  • Loading branch information
pacrob committed Oct 25, 2023
1 parent 3c4c05d commit dce3dcf
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 16 deletions.
12 changes: 10 additions & 2 deletions docs/hexbytes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ Install with:

.. code-block:: bash
pip install hexbytes
python -m pip install hexbytes
Example :class:`~hexbytes.main.HexBytes` usage:

::
.. doctest::

>>> from hexbytes import HexBytes

Expand All @@ -22,8 +22,16 @@ Example :class:`~hexbytes.main.HexBytes` usage:

# HexBytes accepts the hex string representation as well, ignoring case and 0x prefixes
>>> hb = HexBytes('03087766BF68E78671D1EA436AE087DA74A12761DAC020011A9EDDC4900BF13B')
>>> hb
HexBytes('0x03087766bf68e78671d1ea436ae087da74a12761dac020011a9eddc4900bf13b')

# HexBytes does not override the .hex() or __str__ methods of the parent `bytes` type
>>> hb = HexBytes('03087766BF68E78671D1EA436AE087DA74A12761DAC020011A9EDDC4900BF13B')
>>> hb.hex()
'03087766bf68e78671d1ea436ae087da74a12761dac020011a9eddc4900bf13b'
>>> print(hb)
b"\x03\x08wf\xbfh\xe7\x86q\xd1\xeaCj\xe0\x87\xdat\xa1'a\xda\xc0 \x01\x1a\x9e\xdd\xc4\x90\x0b\xf1;"

# get the first byte:
>>> hb[0]
3
Expand Down
17 changes: 3 additions & 14 deletions hexbytes/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,27 +31,16 @@ class HexBytes(bytes):
"""
HexBytes is a *very* thin wrapper around the python built-in :class:`bytes` class.
It has these three changes:
It has these changes:
1. Accepts more initializing values, like hex strings, non-negative integers,
and booleans
2. Returns hex with prefix '0x' from :meth:`HexBytes.hex`
3. The representation at console is in hex
2. The representation at console (__repr__) is 0x-prefixed
"""

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

def hex(
self, sep: Union[str, bytes] = None, bytes_per_sep: "SupportsIndex" = 1
) -> str:
"""
Output hex-encoded bytes, with an "0x" prefix.
Everything following the "0x" is output exactly like :meth:`bytes.hex`.
"""
return "0x" + super().hex()

@overload
def __getitem__(self, key: "SupportsIndex") -> int: # noqa: F811
...
Expand All @@ -70,4 +59,4 @@ def __getitem__( # noqa: F811
return result

def __repr__(self) -> str:
return f"HexBytes({self.hex()!r})"
return f"HexBytes({'0x' + self.hex()!r})"
1 change: 1 addition & 0 deletions newsfragments/38.breaking.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Move HexBytes prepend of ``0x`` from ``hex`` method to ``__repr__`` to not break ``hex`` of parent ``bytes`` class
5 changes: 5 additions & 0 deletions tests/core/test_hexbytes.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ def test_pretty_output():
assert repr(hb) == "HexBytes('0x0f1a')"


def test_does_not_break_bytes_hex():
hb = HexBytes(b"\x0F\x1a")
assert hb.hex() == "0f1a"


@given(st.binary(), st.integers())
def test_hexbytes_index(primitive, index):
hexbytes = HexBytes(primitive)
Expand Down

0 comments on commit dce3dcf

Please sign in to comment.