Skip to content
Closed
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 98 additions & 2 deletions Objects/memoryobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -2332,7 +2332,9 @@ ptr_from_tuple(Py_buffer *view, PyObject *tup)

/* Return the item at index. In a one-dimensional view, this is an object
with the type specified by view->format. Otherwise, the item is a sub-view.
The function is used in memory_subscript() and memory_as_sequence. */
The function is used by memory_subscript(), memoryiter_next() and
memory_as_sequence.
Note: Iteration of multi-dimensional arrays is not yet implemented */
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can revert this whole comment, you no longer use memory_item in memoryiter_next.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

static PyObject *
memory_item(PyMemoryViewObject *self, Py_ssize_t index)
{
Expand Down Expand Up @@ -3160,6 +3162,100 @@ static PyMethodDef memory_methods[] = {
{NULL, NULL}
};

/**************************************************************************/
/* Memoryview Iterator */
/**************************************************************************/

typedef struct {
PyObject_HEAD
Py_ssize_t it_index;
PyMemoryViewObject *it_seq; // Set to NULL when iterator is exhausted
} memoryiterobject;


static void memoryiter_dealloc(memoryiterobject *);
static int memoryiter_traverse(memoryiterobject * , visitproc, void *);
static PyObject *memoryiter_next(memoryiterobject *);
static PyObject *memory_iter(PyObject *);


static PyTypeObject PyMemoryIter_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
.tp_name = "memory_iterator",
.tp_basicsize = sizeof(memoryiterobject),
// methods
.tp_dealloc = (destructor)memoryiter_dealloc,
.tp_getattro = PyObject_GenericGetAttr,
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
.tp_traverse = (traverseproc)memoryiter_traverse,
.tp_iter = PyObject_SelfIter,
.tp_iternext = (iternextfunc)memoryiter_next,
};

static void
memoryiter_dealloc(memoryiterobject *it)
{
_PyObject_GC_UNTRACK(it);
Py_XDECREF(it->it_seq);
PyObject_GC_Del(it);
}

static int
memoryiter_traverse(memoryiterobject *it, visitproc visit, void *arg)
{
Py_VISIT(it->it_seq);
return 0;
}

static PyObject *
memoryiter_next(memoryiterobject *it)
{
PyMemoryViewObject *seq;
seq = it->it_seq;
if (seq == NULL) {
return NULL;
}

if (it->it_index < memory_length(seq)) {
return memory_item(seq, it->it_index++);
}

it->it_seq = NULL;
Py_DECREF(seq);
return NULL;
}

static PyObject *
memory_iter(PyObject *seq)
{
if (!PyMemoryView_Check(seq)) {
PyErr_BadInternalCall();
return NULL;
}

int ndims = ((PyMemoryViewObject *)seq)->view.ndim;
if (ndims == 0) {
PyErr_SetString(PyExc_TypeError, "invalid indexing of 0-dim memory");
return NULL;
}
if (ndims != 1) {
PyErr_SetString(PyExc_NotImplementedError,
"multi-dimensional sub-views are not implemented");
return NULL;
}

memoryiterobject *it;
it = PyObject_GC_New(memoryiterobject, &PyMemoryIter_Type);
if (it == NULL) {
return NULL;
}

it->it_index = 0;
Py_INCREF(seq);
it->it_seq = (PyMemoryViewObject *)seq;
_PyObject_GC_TRACK(it);
return (PyObject *)it;
}

PyTypeObject PyMemoryView_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
Expand Down Expand Up @@ -3187,7 +3283,7 @@ PyTypeObject PyMemoryView_Type = {
(inquiry)memory_clear, /* tp_clear */
memory_richcompare, /* tp_richcompare */
offsetof(PyMemoryViewObject, weakreflist),/* tp_weaklistoffset */
0, /* tp_iter */
memory_iter, /* tp_iter */
0, /* tp_iternext */
memory_methods, /* tp_methods */
0, /* tp_members */
Expand Down