Skip to content

Commit 474b369

Browse files
cmaloneyclaude
andcommitted
Remove unique temporary adoption optimizations
PyUnstable_Object_IsUniqueReferencedTemporary() can't tell when a C caller still holds a borrowed reference to the argument (for example bisect.insort(lst, bytearray(b'abc')[1:], key=bytes)), so adopting the buffer empties an object still in use. Leave the optimization for a follow-up and keep this PR to the vectorcall change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 8e0d8a2 commit 474b369

3 files changed

Lines changed: 0 additions & 50 deletions

File tree

‎Lib/test/test_bytes.py‎

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import sys
1717
import tempfile
1818
import textwrap
19-
lazy import tracemalloc
2019
import threading
2120
import unittest
2221
from _codecs import _unregister_error as _codecs_unregister_error
@@ -1810,23 +1809,6 @@ def hashing_codec(name):
18101809
self.assertEqual(taken, b'Hello')
18111810
self.assertEqual(hash(taken), hash(b'Hello'))
18121811

1813-
@support.cpython_only
1814-
@support.bigmemtest(size=support._1G, memuse=1)
1815-
def test_unique_temporary_take_memory(self, size):
1816-
# Optimization: When passed a unique temporary adopt it rather than
1817-
# allocate + copy + deallocate.
1818-
def peak(func):
1819-
tracemalloc.start()
1820-
try:
1821-
func()
1822-
return tracemalloc.get_traced_memory()[1]
1823-
finally:
1824-
tracemalloc.stop()
1825-
# Copy would be 2.0, 1.5 gives space for other allocations.
1826-
self.assertLess(peak(lambda: bytearray(bytes(size))), size * 1.5)
1827-
self.assertLess(peak(lambda: bytearray(bytearray(size))), size * 1.5)
1828-
self.assertLess(peak(lambda: bytes(bytearray(size))), size * 1.5)
1829-
18301812
def test_take_bytes_reentrant_resize(self):
18311813
# gh-153570: n.__index__() can resize the bytearray, so take_bytes()
18321814
# must re-read the size afterwards. It cached the size before the

‎Objects/bytearrayobject.c‎

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,33 +1083,6 @@ bytearray___init___impl(PyByteArrayObject *self, PyObject *arg,
10831083
}
10841084
}
10851085

1086-
/* optimization: Adopt bytes rather than copying. */
1087-
if (PyBytes_CheckExact(arg)
1088-
&& PyUnstable_Object_IsUniqueReferencedTemporary(arg)
1089-
&& _PyBytes_GET_CACHED_HASH((PyBytesObject *)arg) == -1)
1090-
{
1091-
/* Reinit before taking a reference: it asserts the bytes is
1092-
uniquely referenced. */
1093-
self->ob_bytes_object = arg;
1094-
bytearray_reinit_from_bytes(self, PyBytes_GET_SIZE(arg));
1095-
Py_INCREF(arg);
1096-
return 0;
1097-
}
1098-
1099-
/* optimization: Adopt bytearray rather than copying. */
1100-
if (PyByteArray_CheckExact(arg)
1101-
&& PyUnstable_Object_IsUniqueReferencedTemporary(arg))
1102-
{
1103-
PyObject *bytes = bytearray_take_bytes_impl((PyByteArrayObject *)arg,
1104-
Py_None);
1105-
if (bytes == NULL) {
1106-
return -1;
1107-
}
1108-
self->ob_bytes_object = bytes;
1109-
bytearray_reinit_from_bytes(self, PyBytes_GET_SIZE(bytes));
1110-
return 0;
1111-
}
1112-
11131086
/* Use the buffer API */
11141087
if (PyObject_CheckBuffer(arg)) {
11151088
Py_ssize_t size;

‎Objects/bytesobject.c‎

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3003,11 +3003,6 @@ bytes_new_impl(PyTypeObject *type, PyObject *x, const char *encoding,
30033003
bytes = _PyBytes_FromSizeZero(size);
30043004
}
30053005
}
3006-
/* Adopt unique temporary bytearray rather than copying. */
3007-
else if (PyByteArray_CheckExact(x)
3008-
&& PyUnstable_Object_IsUniqueReferencedTemporary(x)) {
3009-
bytes = PyObject_CallMethodNoArgs(x, &_Py_ID(take_bytes));
3010-
}
30113006
else {
30123007
bytes = PyBytes_FromObject(x);
30133008
}

0 commit comments

Comments
 (0)