question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How does `__bytes__` work for NumPy arrays?

See original GitHub issue

NumPy arrays support __bytes__, which is really great. Though after spending a bit looking at the code, it is not clear how this works. Would someone be able to provide some insight on how this works? Thanks in advance 🙂

Reproducing code example:

In [1]: import numpy as np                                                      

In [2]: a = np.arange(6, dtype="u1").reshape((2, 3), order="F"); a              
Out[2]: 
array([[0, 2, 4],
       [1, 3, 5]], dtype=uint8)

In [3]: a.tobytes()                                                             
Out[3]: b'\x00\x02\x04\x01\x03\x05'

In [4]: bytes(a)                                                                
Out[4]: b'\x00\x02\x04\x01\x03\x05'

Error message:

Nothing! It works great 😄

Numpy/Python version information:

1.18.1 3.6.7 | packaged by conda-forge | (default, Nov  6 2019, 16:03:31) 
[GCC Clang 9.0.0 (tags/RELEASE_900/final)]

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:1
  • Comments:7 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
mattipcommented, Mar 5, 2020

Closing, I think the question was answered. Please re-open if there is a need.

1reaction
eric-wiesercommented, Mar 4, 2020

Note that your test is misleading, (1) is not the tuple (1,) but just 1. It turns out not to matter though.

What you’re seeing is that the bytes(int) constructor takes precedence over the bytes(buffer) constructor. More specifically, if operator.index(i) works, then memoryview(i) is never tried

If you do bytes(np.int32(4)), you get four zeros. If you do bytes(np.float32(4)), you get the bytes representation of the float.

Unfortunately there’s nothing numpy can do about this. It might be worth suggesting a patch to CPython, changing the semantics from:

def bytes(x):
    try:
        x_int = operator.index(x)
    except TypeError:
        pass
    else:
        return bytes_of_n_zeros(x_int)

    try:
        x_buffer = memoryview(x)
    except TypeError:
        pass
    else:
        return bytes_from_buffer(x_buffer)

    raise TypeError

to

def bytes(x):
    try:
        x_int = operator.index(x)
    except TypeError:
        x_int = None
    try:
        x_buffer = memoryview(x)
    except TypeError:
        x_buffer = None
 
    if x_int is not None and x_buffer is not None:
        warnings.warn("bytes(x) is ambigious - use `bytes(operator.index(x))` or `bytes(memoryview(x))`)
        return bytes_of_n_zeros(x_int)
    elif x_int is not None:
        return bytes_of_n_zeros(x_int)
    elif x_buffer is not None:
        return bytes_of_n_zeros(x_buffer)
    else:
        raise TypeError
Read more comments on GitHub >

github_iconTop Results From Across the Web

Convert byte array back to numpy array - Stack Overflow
If you want to make sure the arrays are equal, you have to use np.array_equal . Using == will do an elementwise operation, ......
Read more >
numpy.frombuffer — NumPy v1.24 Manual
Inverse of this operation, construct Python bytes from the raw data bytes in the array. Notes. If the buffer has data that is...
Read more >
NumPy: Convert a given array into bytes, and load it as array
NumPy Basic Exercises, Practice and Solution: Write a NumPy program to convert a given array into bytes, and load it as array.
Read more >
Byte Swapping in NumPy - Scaler Topics
It is used to switch between low-endian and big-endian data representations by returning a byte swapped array, which can be swapped in-place if ......
Read more >
Find length of one array element in bytes and total bytes ...
In NumPy we can find the length of one array element in a byte with the help of itemsize . It will return...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found