GeezerVison is showing github.com — [3.13] gh-157048: check for buffer errors before mutating in BytesIO.… · python/cpython@88f6017
File tree
Expand file treeCollapse file tree
Open diff view settings
Expand file treeCollapse file tree
Open diff view settings
Collapse file
Copy file name to clipboardExpand all lines: Lib/test/test_memoryio.py +12Lines changed: 12 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -920,6 +920,18 @@ def test_cow_mutable(self): |
920 | 920 | memio = self.ioclass(ba) |
921 | 921 | self.assertEqual(sys.getrefcount(ba), old_rc) |
922 | 922 |
|
| 923 | + def test_write_with_export(self): |
| 924 | + memio = self.ioclass(b"abcd") |
| 925 | + memio.seek(2) |
| 926 | + with memio.getbuffer() as view: |
| 927 | + self.assertRaises(BufferError, memio.__init__, b"replacement") |
| 928 | + self.assertEqual(memio.tell(), 2) |
| 929 | + self.assertEqual(memio.getvalue(), b"abcd") |
| 930 | + self.assertEqual(bytes(view), b"abcd") |
| 931 | + memio.write(b"X") |
| 932 | + self.assertEqual(memio.getvalue(), b"abXd") |
| 933 | + |
| 934 | + |
923 | 935 | class CStringIOTest(PyStringIOTest): |
924 | 936 | ioclass = io.StringIO |
925 | 937 | UnsupportedOperation = io.UnsupportedOperation |
|
Collapse file
Copy file name to clipboard +2Lines changed: 2 additions & 0 deletions - Display the source diff
- Display the rich diff
| Original file line number | Diff line number | Diff line change |
|---|
|
| 1 | +Preserve the position and contents of :class:`io.BytesIO` when |
| 2 | +:meth:`!BytesIO.__init__` fails because a buffer is exported. |
Collapse file
Copy file name to clipboardExpand all lines: Modules/_io/bytesio.c +5-4Lines changed: 5 additions & 4 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -943,15 +943,16 @@ static int |
943 | 943 | _io_BytesIO___init___impl(bytesio *self, PyObject *initvalue) |
944 | 944 | /*[clinic end generated code: output=65c0c51e24c5b621 input=aac7f31b67bf0fb6]*/ |
945 | 945 | { |
946 | | - /* In case, __init__ is called multiple times. */ |
947 | | - self->string_size = 0; |
948 | | - self->pos = 0; |
949 | | - |
950 | 946 | if (self->exports > 0) { |
951 | 947 | PyErr_SetString(PyExc_BufferError, |
952 | 948 | "Existing exports of data: object cannot be re-sized"); |
953 | 949 | return -1; |
954 | 950 | } |
| 951 | + |
| 952 | + /* In case, __init__ is called multiple times. */ |
| 953 | + self->string_size = 0; |
| 954 | + self->pos = 0; |
| 955 | + |
955 | 956 | if (initvalue && initvalue != Py_None) { |
956 | 957 | if (PyBytes_CheckExact(initvalue)) { |
957 | 958 | Py_XSETREF(self->buf, Py_NewRef(initvalue)); |
|