Skip to content

Commit 5a55e31

Browse files
committed
corrected handling for contiguous iter holding a an empty iter
1 parent 1b49eaa commit 5a55e31

File tree

2 files changed

+25
-10
lines changed

2 files changed

+25
-10
lines changed

src/_arraykit.c

+8-9
Original file line numberDiff line numberDiff line change
@@ -4715,6 +4715,8 @@ typedef struct BIIterContiguousObject {
47154715
bool reduce; // optionally reduce slices to integers
47164716
} BIIterContiguousObject;
47174717

4718+
4719+
// Create a new contiguous slice iterator. Return NULL on error. Steals a reference to PyObject* iter.
47184720
static PyObject *
47194721
BIIterContiguous_new(BlockIndexObject *bi,
47204722
bool reversed,
@@ -4728,9 +4730,7 @@ BIIterContiguous_new(BlockIndexObject *bi,
47284730
Py_INCREF((PyObject*)bi);
47294731
bii->bi = bi;
47304732

4731-
Py_INCREF(iter);
4732-
bii->iter = iter;
4733-
4733+
bii->iter = iter; // steals ref
47344734
bii->reversed = reversed;
47354735

47364736
bii->last_block = -1;
@@ -4790,9 +4790,8 @@ BIIterContiguous_reversed(BIIterContiguousObject *self)
47904790
}
47914791
PyObject* biiter = BIIterContiguous_new(self->bi,
47924792
reversed,
4793-
self->iter,
4793+
iter, // steals ref
47944794
self->reduce);
4795-
Py_DECREF(iter);
47964795
return biiter;
47974796
}
47984797

@@ -4832,6 +4831,9 @@ BIIterContiguous_iternext(BIIterContiguousObject *self)
48324831
}
48334832
// no more pairs, return previous slice_start, flag for end on next call
48344833
self->next_block = -2;
4834+
if (self->last_block == -1) { // iter produced no values, terminate
4835+
break;
4836+
}
48354837
return AK_build_pair_ssize_t_slice( // steals ref
48364838
self->last_block,
48374839
AK_build_slice_inclusive(slice_start,
@@ -5488,14 +5490,11 @@ BlockIndex_iter_contiguous(BlockIndexObject *self, PyObject *args, PyObject *kwa
54885490
)) {
54895491
return NULL;
54905492
}
5491-
5492-
// might need to store enum type for branching
54935493
PyObject* iter = BIIterSelector_new(self, selector, 0, BIIS_UNKNOWN, ascending);
54945494
if (iter == NULL) {
54955495
return NULL; // exception set
54965496
}
5497-
PyObject* biiter = BIIterContiguous_new(self, 0, iter, reduce); // might be NULL, will incref iter
5498-
Py_DECREF(iter);
5497+
PyObject* biiter = BIIterContiguous_new(self, 0, iter, reduce); // might be NULL, steals iter ref
54995498
return biiter;
55005499
}
55015500

test/test_block_index.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -795,8 +795,24 @@ def test_block_index_iter_contiguous_h2(self) -> None:
795795
(1, 1)])
796796

797797

798-
def test_block_index_iter_contiguous_i(self) -> None:
798+
def test_block_index_iter_contiguous_i1(self) -> None:
799799
bi1 = BlockIndex()
800800
bi1.register(np.arange(6).reshape(2,3))
801801
bi1.register(np.arange(6).reshape(2,3))
802802

803+
self.assertEqual(list(bi1.iter_select(slice(0, 0))), [])
804+
self.assertEqual(list(bi1.iter_contiguous(slice(0, 0))), [])
805+
806+
self.assertEqual(list(bi1.iter_select(slice(30, 60, 2))), [])
807+
self.assertEqual(list(bi1.iter_contiguous(slice(30, 60, 2))), [])
808+
809+
def test_block_index_iter_contiguous_i2(self) -> None:
810+
bi1 = BlockIndex()
811+
bi1.register(np.arange(6).reshape(2,3))
812+
bi1.register(np.arange(6).reshape(2,3))
813+
814+
self.assertEqual(list(bi1.iter_select([])), [])
815+
self.assertEqual(list(bi1.iter_contiguous([])), [])
816+
817+
self.assertEqual(list(bi1.iter_select(np.full(len(bi1), False))), [])
818+
self.assertEqual(list(bi1.iter_contiguous(np.full(len(bi1), False))), [])

0 commit comments

Comments
 (0)