|
|
@ -243,7 +243,7 @@ PyObject* PyUpb_RepeatedContainer_ToList(PyObject* _self) { |
|
|
|
PyObject* list = PyList_New(n); |
|
|
|
PyObject* list = PyList_New(n); |
|
|
|
for (size_t i = 0; i < n; i++) { |
|
|
|
for (size_t i = 0; i < n; i++) { |
|
|
|
PyObject* val = PyUpb_UpbToPy(upb_array_get(arr, i), f, self->arena); |
|
|
|
PyObject* val = PyUpb_UpbToPy(upb_array_get(arr, i), f, self->arena); |
|
|
|
PyList_SetItem(list, n, val); |
|
|
|
PyList_SetItem(list, i, val); |
|
|
|
} |
|
|
|
} |
|
|
|
return list; |
|
|
|
return list; |
|
|
|
} |
|
|
|
} |
|
|
@ -315,7 +315,9 @@ static int PyUpb_RepeatedContainer_SetSubscript( |
|
|
|
// Set range.
|
|
|
|
// Set range.
|
|
|
|
PyObject* seq = |
|
|
|
PyObject* seq = |
|
|
|
PySequence_Fast(value, "must assign iterable to extended slice"); |
|
|
|
PySequence_Fast(value, "must assign iterable to extended slice"); |
|
|
|
|
|
|
|
PyObject* item = NULL; |
|
|
|
if (!seq) return -1; |
|
|
|
if (!seq) return -1; |
|
|
|
|
|
|
|
int ret = -1; |
|
|
|
if (PySequence_Size(seq) != count) { |
|
|
|
if (PySequence_Size(seq) != count) { |
|
|
|
PyErr_Format(PyExc_ValueError, |
|
|
|
PyErr_Format(PyExc_ValueError, |
|
|
|
"attempt to assign sequence of size %zd to extended slice " |
|
|
|
"attempt to assign sequence of size %zd to extended slice " |
|
|
@ -326,35 +328,37 @@ static int PyUpb_RepeatedContainer_SetSubscript( |
|
|
|
} |
|
|
|
} |
|
|
|
for (Py_ssize_t i = 0; i < count; i++, idx += step) { |
|
|
|
for (Py_ssize_t i = 0; i < count; i++, idx += step) { |
|
|
|
upb_msgval msgval; |
|
|
|
upb_msgval msgval; |
|
|
|
PyObject* item = PySequence_GetItem(seq, i); |
|
|
|
item = PySequence_GetItem(seq, i); |
|
|
|
|
|
|
|
if (!item) goto err; |
|
|
|
// XXX: if this fails we can leave the list partially mutated.
|
|
|
|
// XXX: if this fails we can leave the list partially mutated.
|
|
|
|
bool ok = PyUpb_PyToUpb(item, f, &msgval, arena); |
|
|
|
if (!PyUpb_PyToUpb(item, f, &msgval, arena)) goto err; |
|
|
|
Py_DECREF(item); |
|
|
|
|
|
|
|
if (!ok) return -1; |
|
|
|
|
|
|
|
upb_array_set(arr, idx, msgval); |
|
|
|
upb_array_set(arr, idx, msgval); |
|
|
|
} |
|
|
|
} |
|
|
|
return 0; |
|
|
|
ret = 0; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
err: |
|
|
|
|
|
|
|
Py_XDECREF(seq); |
|
|
|
|
|
|
|
Py_XDECREF(item); |
|
|
|
|
|
|
|
return ret; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int PyUpb_RepeatedContainer_DeleteSubscript(upb_array* arr, |
|
|
|
static int PyUpb_RepeatedContainer_DeleteSubscript(upb_array* arr, |
|
|
|
Py_ssize_t idx, |
|
|
|
Py_ssize_t idx, |
|
|
|
Py_ssize_t count, |
|
|
|
Py_ssize_t count, |
|
|
|
Py_ssize_t step) { |
|
|
|
Py_ssize_t step) { |
|
|
|
// This is a delete, not a set.
|
|
|
|
|
|
|
|
// Normalize direction: deletion is order-independent.
|
|
|
|
// Normalize direction: deletion is order-independent.
|
|
|
|
if (step > 0) { |
|
|
|
Py_ssize_t start = idx; |
|
|
|
idx += step * (count - 1); |
|
|
|
if (step < 0) { |
|
|
|
|
|
|
|
Py_ssize_t end = start + step * (count - 1); |
|
|
|
|
|
|
|
start = end; |
|
|
|
step = -step; |
|
|
|
step = -step; |
|
|
|
} |
|
|
|
} |
|
|
|
if (step == -1) { |
|
|
|
size_t dst = start; |
|
|
|
// Contiguous range.
|
|
|
|
size_t src = start + 1; |
|
|
|
upb_array_delete(arr, idx - (count - 1), count); |
|
|
|
for (Py_ssize_t i = 0; i < count; i++, dst += step, src += step + 1) { |
|
|
|
} else { |
|
|
|
upb_array_move(arr, dst, src, step); |
|
|
|
// Stepped slice.
|
|
|
|
|
|
|
|
for (Py_ssize_t i = 0; i < count; i++, idx += step) { |
|
|
|
|
|
|
|
upb_array_delete(arr, idx, 1); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
upb_array_resize(arr, upb_array_size(arr) - count, NULL); |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|