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: confusing BufferError: Existing exports of data: object cannot be re-sized
Type: behavior Stage: patch review
Components: Interpreter Core Versions:
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Jeffrey.Kintscher, pewscorner
Priority: normal Keywords: patch

Created on 2020-06-24 07:29 by arigo, last changed 2022-04-11 14:59 by admin.

Pull Requests
URL Status Linked Edit
PR 21792 open Jeffrey.Kintscher, 2020-08-09 06:12
Messages (4)
msg372237 - (view) Author: Armin Rigo (arigo) * (Python committer) Date: 2020-06-24 07:29
The behavior (tested in 3.6 and 3.9) of io.BytesIO().getbuffer() gives a unexpected exception message:

>>> b = io.BytesIO()
>>> b.write(b'abc')
3
>>> buf = b.getbuffer()
>>> b.seek(0)
0
>>> b.write(b'?')     # or anything up to 3 bytes
BufferError: Existing exports of data: object cannot be re-sized

The error message pretends that the problem is in resizing the BytesIO object, but the write() is not actually causing any resize.

I am not sure if the bug is a wrong error message (and all writes are supposed to be forbidden) or a wrongly forbidden write() (after all, we can use the buffer itself to write into the same area of memory).
msg372286 - (view) Author: PEW's Corner (pewscorner) * Date: 2020-06-24 21:56
I'm getting the same error (in 3.8.3) for this code:

o = bytearray(1)
o += o

There's no error if the second line is replaced with:

o += bytearray(1)

Not sure if this is related.
msg375061 - (view) Author: Jeffrey Kintscher (Jeffrey.Kintscher) * Date: 2020-08-08 21:28
The error message is found in three different locations in the source code.  One is in the bytearray class, and the other two are in the BytesIO class.  They are unrelated code paths.
msg375063 - (view) Author: Jeffrey Kintscher (Jeffrey.Kintscher) * Date: 2020-08-09 00:00
>>> import io
>>> b = io.BytesIO()
>>> b.write(b'abc')
3
>>> buf = b.getbuffer()
>>> b.seek(0)
0
>>> b.write(b'?')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
BufferError: Existing exports of data: object cannot be re-sized
>>> 


The problem is caused by the b.getbuffer() call.  It increments a reference counter in the BytesIO object that causes the b.write() call to fail because the counter is > 0. The error message is misleading.  The counter is decremented when the buffer view is deleted.


>>> import io
>>> b = io.BytesIO()
>>> b.write(b'abc')
3
>>> buf = b.getbuffer()
>>> b.seek(0)
0
>>> b.write(b'?')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
BufferError: Existing exports of data: object cannot be re-sized
>>> del buf
>>> b.write(b'?')
1
>>> b.getvalue()
b'?bc'
>>> 


The documentation for io.BytesIO.getbuffer() says "Note:  As long as the view exists, the BytesIO object cannot be resized or closed."  Either this is a bug, or the documentation needs to be updated to say the io.BytesIO object is unwritable while any buffer views exist.
History
Date User Action Args
2022-04-11 14:59:32adminsetgithub: 85269
2020-08-09 06:12:38Jeffrey.Kintschersetkeywords: + patch
stage: test needed -> patch review
pull_requests: + pull_request20931
2020-08-09 00:00:43Jeffrey.Kintschersetmessages: + msg375063
2020-08-08 21:28:06Jeffrey.Kintschersetnosy: + Jeffrey.Kintscher
messages: + msg375061
2020-06-24 21:56:22pewscornersetnosy: + pewscorner
messages: + msg372286
2020-06-24 07:30:14arigosetnosy: - arigo
-> (no value)
2020-06-24 07:29:18arigocreate