@@ -3356,12 +3356,14 @@ AK_build_slice(Py_ssize_t start, Py_ssize_t stop, Py_ssize_t step)
3356
3356
return new ;
3357
3357
}
3358
3358
3359
- // Given inclusive start, end indices, returns a new reference to a slice. Returns NULL on error.
3359
+ // Given inclusive start, end indices, returns a new reference to a slice. Returns NULL on error. If `reduce` is True, single width slices return an integer.
3360
3360
static inline PyObject *
3361
- AK_build_slice_inclusive (Py_ssize_t start , Py_ssize_t end )
3361
+ AK_build_slice_inclusive (Py_ssize_t start , Py_ssize_t end , bool reduce )
3362
3362
{
3363
- // TODO: if start and end are the same, return an integer; this can be configured with a parameter
3364
- assert (start >= 0 );
3363
+ if (reduce && start == end ) {
3364
+ return PyLong_FromSsize_t (start ); // new ref
3365
+ }
3366
+ // assert(start >= 0);
3365
3367
if (start <= end ) {
3366
3368
return AK_build_slice (start , end + 1 , 1 );
3367
3369
}
@@ -4654,10 +4656,15 @@ typedef struct BIIterContiguousObject {
4654
4656
Py_ssize_t last_column ;
4655
4657
Py_ssize_t next_block ;
4656
4658
Py_ssize_t next_column ;
4659
+ bool reduce ; // optionally reduce slices to integers
4657
4660
} BIIterContiguousObject ;
4658
4661
4659
4662
static PyObject *
4660
- BIIterContiguous_new (BlockIndexObject * bi , int8_t reversed , PyObject * iter ) {
4663
+ BIIterContiguous_new (BlockIndexObject * bi ,
4664
+ int8_t reversed ,
4665
+ PyObject * iter ,
4666
+ bool reduce )
4667
+ {
4661
4668
BIIterContiguousObject * bii = PyObject_New (BIIterContiguousObject , & BIIterContiguousType );
4662
4669
if (!bii ) {
4663
4670
return NULL ;
@@ -4672,6 +4679,7 @@ BIIterContiguous_new(BlockIndexObject *bi, int8_t reversed, PyObject* iter) {
4672
4679
bii -> last_column = -1 ;
4673
4680
bii -> next_block = -1 ;
4674
4681
bii -> next_column = -1 ;
4682
+ bii -> reduce = reduce ;
4675
4683
4676
4684
return (PyObject * )bii ;
4677
4685
}
@@ -4726,7 +4734,9 @@ BIIterContiguous_iternext(BIIterContiguousObject *self) {
4726
4734
self -> next_block = -2 ;
4727
4735
return Py_BuildValue ("nN" , // N steals ref
4728
4736
self -> last_block ,
4729
- AK_build_slice_inclusive (slice_start , self -> last_column ));
4737
+ AK_build_slice_inclusive (slice_start ,
4738
+ self -> last_column ,
4739
+ self -> reduce ));
4730
4740
}
4731
4741
// i is gauranteed to be within the range of self->bit_count at this point; the only source of arbitrary indices is in BIIterSeq_iternext_core, and that function validates the range
4732
4742
BlockIndexRecord * biri = & self -> bi -> bir [i ];
@@ -4749,7 +4759,9 @@ BIIterContiguous_iternext(BIIterContiguousObject *self) {
4749
4759
self -> next_column = column ;
4750
4760
return Py_BuildValue ("nN" , // N steals ref
4751
4761
self -> last_block ,
4752
- AK_build_slice_inclusive (slice_start , self -> last_column ));
4762
+ AK_build_slice_inclusive (slice_start ,
4763
+ self -> last_column ,
4764
+ self -> reduce ));
4753
4765
}
4754
4766
return NULL ;
4755
4767
}
@@ -4778,7 +4790,10 @@ BIIterContiguous_reversed(BIIterContiguousObject *self) {
4778
4790
!self -> reversed ,
4779
4791
BIIS_UNKNOWN , // let type be determined by selector
4780
4792
0 );
4781
- PyObject * biiter = BIIterContiguous_new (self -> bi , !self -> reversed , self -> iter );
4793
+ PyObject * biiter = BIIterContiguous_new (self -> bi ,
4794
+ !self -> reversed ,
4795
+ self -> iter ,
4796
+ self -> reduce );
4782
4797
Py_DECREF (iter );
4783
4798
return biiter ;
4784
4799
}
@@ -5389,6 +5404,7 @@ BlockIndex_iter_select(BlockIndexObject *self, PyObject *selector){
5389
5404
static char * iter_contiguous_kargs_names [] = {
5390
5405
"selector" ,
5391
5406
"ascending" ,
5407
+ "reduce" ,
5392
5408
NULL
5393
5409
};
5394
5410
@@ -5398,19 +5414,21 @@ BlockIndex_iter_contiguous(BlockIndexObject *self, PyObject *args, PyObject *kwa
5398
5414
{
5399
5415
PyObject * selector ;
5400
5416
int ascending = 0 ;
5417
+ int reduce = 0 ;
5401
5418
5402
5419
if (!PyArg_ParseTupleAndKeywords (args , kwargs ,
5403
- "O|$p :iter_contiguous" ,
5420
+ "O|$pp :iter_contiguous" ,
5404
5421
iter_contiguous_kargs_names ,
5405
5422
& selector ,
5406
- & ascending
5423
+ & ascending ,
5424
+ & reduce
5407
5425
)) {
5408
5426
return NULL ;
5409
5427
}
5410
5428
5411
5429
// might need to store enum type for branching
5412
5430
PyObject * iter = BIIterSelector_new (self , selector , 0 , BIIS_UNKNOWN , ascending );
5413
- PyObject * biiter = BIIterContiguous_new (self , 0 , iter ); // will incref iter
5431
+ PyObject * biiter = BIIterContiguous_new (self , 0 , iter , reduce ); // will incref iter
5414
5432
Py_DECREF (iter );
5415
5433
5416
5434
return biiter ;
0 commit comments