with self.assertRaises((MemoryError, OverflowError)):
lst *= size
+ def test_repr_mutate(self):
+ class Obj:
+ @staticmethod
+ def __repr__():
+ try:
+ mylist.pop()
+ except IndexError:
+ pass
+ return 'obj'
+
+ mylist = [Obj() for _ in range(5)]
+ self.assertEqual(repr(mylist), '[obj, obj, obj]')
+
def test_repr_large(self):
# Check the repr of large list objects
def check(n):
{
PyObject *s;
_PyUnicodeWriter writer;
+ PyObject *item = NULL;
Py_ssize_t i = Py_ReprEnter((PyObject*)v);
if (i != 0) {
return i > 0 ? PyUnicode_FromString("[...]") : NULL;
/* Do repr() on each element. Note that this may mutate the list,
so must refetch the list size on each iteration. */
for (i = 0; i < Py_SIZE(v); ++i) {
+ /* Hold a strong reference since repr(item) can mutate the list */
+ item = Py_NewRef(v->ob_item[i]);
+
if (i > 0) {
if (_PyUnicodeWriter_WriteASCIIString(&writer, ", ", 2) < 0)
goto error;
}
- s = PyObject_Repr(v->ob_item[i]);
+ s = PyObject_Repr(item);
if (s == NULL)
goto error;
goto error;
}
Py_DECREF(s);
+ Py_CLEAR(item);
}
writer.overallocate = 0;
return _PyUnicodeWriter_Finish(&writer);
error:
+ Py_XDECREF(item);
_PyUnicodeWriter_Dealloc(&writer);
Py_ReprLeave((PyObject *)v);
return NULL;