This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: "TypeError: 'int' does not have the buffer interface" on memoryview over bytearray
Type: behavior Stage:
Components: Versions: Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: benjamin.peterson, brett.cannon, serhiy.storchaka, skrah, vpelletier
Priority: normal Keywords:

Created on 2017-02-01 00:00 by vpelletier, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (6)
msg286567 - (view) Author: Vincent Pelletier (vpelletier) Date: 2017-02-01 00:00
Quoting a github gist[1] (not mine, I found it while googling for this error) clearly illustrating the issue:

# Python 2
>>> b = bytearray(8)
>>> v = memoryview(b)
>>> v[0] = 42
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' does not have the buffer interface
>>> b
bytearray(b'\x00\x00\x00\x00\x00\x00\x00\x00')

# Python 3
>>> b = bytearray(8)
>>> v = memoryview(b)
>>> v[0] = 42
>>> b
bytearray(b'*\x00\x00\x00\x00\x00\x00\x00')

This is especially annoying as on python3 bytearray.__setitem__ only accepts integers, making working py2 code totally incompatible with py3 in a 2to3-undetectable way.

[1] https://gist.github.com/superbobry/b90c0cc7c44beaa51ef9
msg286670 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2017-02-01 17:55
I'm not quite sure what you're asking for here. The Python 2.7 semantics can't change because Python 2.7 is only receiving bugfixes. So do you want the Python 3 case to become an error?
msg286777 - (view) Author: Vincent Pelletier (vpelletier) Date: 2017-02-02 12:49
My original point of view was that:
- python3 is right to only accept integers, consistently with "str != bytes"
- python2 is rather right to accept str, consistently with "str == bytes"
- maybe the bug is that python2 should not reject integers, making the upgrade path to python3 (or the backward compatibility with python2, same thing) easy.

The context is that I develop a (pure-python) module interfacing with a C library, and somewhere in there I want to expose a read/write memory area (the bytearray) which first few bytes must not be accessible from the application using my module (because the application does not care about these bytes, and slicing everywhere is not convenient). Also, I do not want to expose ctypes instances (I'm supposed to be the python/C interface so the application does not have to care). So exposing that memory chunk via a memoryview slice over the original bytearray seems (and please do correct me if I am wrong) the right way to implement this:

>>> b = bytearray(16) # the "real" buffer
>>> c = (ctypes.c_char * 16).from_buffer(b) # for C library
>>> v = memoryview(b)[8:] # for host program

But because of this memoryview behaviour difference my API will behave inconsistently between python2 and python3.

My (naïve) initial idea submitting this bug report was that python2 would be modified to tolerate integers passed to memoryview.__setitem__. But I later realised such change would not be sufficient: python2's memoryview.__getitem__ returns strings where python3's returns integers. I agree that changing such visible behaviour in python2 would be bad.

Am I stuck with developing my own proxy class then (likely wrapping memoryview with type-casting glue) ?
msg286780 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2017-02-02 13:11
> - maybe the bug is that python2 should not reject integers, making the upgrade path to python3 (or the backward compatibility with python2, same thing) easy.

It is too late for this.

You can use the helper that converts the argument to appropriate depending on the version.

if PY2:
    def helper(arg):
        if isinstance(ar, (int, long)):
            return chr(arg)
        return arg
else:
    def helper(arg):
        return arg
...
v[0] = helper(42)

Or just have different branches for performance critical code:

if PY2:
    v[0] = b'\x2a'
else:
    v[0] = 42

I don't think Python interpreter should be changed here.
msg286793 - (view) Author: Stefan Krah (skrah) * (Python committer) Date: 2017-02-02 14:07
I agree it's too late to change 2.7, and 3.x cannot (and should not) be changed at this stage.
msg286810 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2017-02-02 17:30
As Serhiy and Stefan pointed out, it's too late to change Python 2.7 semantics. Closing as "not a bug".
History
Date User Action Args
2022-04-11 14:58:42adminsetgithub: 73590
2017-02-02 17:30:15brett.cannonsetstatus: open -> closed
resolution: not a bug
messages: + msg286810
2017-02-02 14:07:57skrahsetmessages: + msg286793
2017-02-02 13:11:38serhiy.storchakasetnosy: + serhiy.storchaka
messages: + msg286780
2017-02-02 12:49:36vpelletiersetmessages: + msg286777
2017-02-01 17:55:18brett.cannonsetnosy: + brett.cannon
messages: + msg286670
2017-02-01 10:13:37serhiy.storchakasetnosy: + benjamin.peterson, skrah
2017-02-01 00:00:11vpelletiercreate