@@ -3263,17 +3263,61 @@ name_filter(PyObject *Py_UNUSED(m), PyObject *n) {
32633263 return n ;
32643264}
32653265
3266+ // Returns NULL on error. Returns a new reference.
3267+ static inline PyObject *
3268+ AK_build_pair_ssize_t (Py_ssize_t a , Py_ssize_t b )
3269+ {
3270+ PyObject * t = PyTuple_New (2 );
3271+ if (t == NULL ) {
3272+ return NULL ;
3273+ }
3274+ PyObject * py_a = PyLong_FromSsize_t (a );
3275+ if (py_a == NULL ) {
3276+ Py_DECREF (t );
3277+ return NULL ;
3278+ }
3279+ PyObject * py_b = PyLong_FromSsize_t (b );
3280+ if (py_b == NULL ) {
3281+ Py_DECREF (t );
3282+ Py_DECREF (py_a );
3283+ return NULL ;
3284+ }
3285+ PyTuple_SET_ITEM (t , 0 , py_a );
3286+ PyTuple_SET_ITEM (t , 1 , py_b );
3287+ return t ;
3288+ }
3289+
3290+ // Returns NULL on error. Returns a new reference. Note that a reference is stolen from the PyObject argument.
3291+ static inline PyObject *
3292+ AK_build_pair_ssize_t_slice (Py_ssize_t a , PyObject * py_b )
3293+ {
3294+ if (py_b == NULL ) { // construction failed
3295+ return NULL ;
3296+ }
3297+ PyObject * t = PyTuple_New (2 );
3298+ if (t == NULL ) {
3299+ return NULL ;
3300+ }
3301+ PyObject * py_a = PyLong_FromSsize_t (a );
3302+ if (py_a == NULL ) {
3303+ Py_DECREF (t );
3304+ return NULL ;
3305+ }
3306+ PyTuple_SET_ITEM (t , 0 , py_a );
3307+ PyTuple_SET_ITEM (t , 1 , py_b );
3308+ return t ;
3309+ }
3310+
32663311// Represent a 1D array as a 2D array with length as rows of a single-column array.
32673312// https://stackoverflow.com/questions/56182259/how-does-one-acces-numpy-multidimensionnal-array-in-c-extensions
32683313static PyObject *
32693314shape_filter (PyObject * Py_UNUSED (m ), PyObject * a ) {
32703315 AK_CHECK_NUMPY_ARRAY_1D_2D (a );
32713316 PyArrayObject * array = (PyArrayObject * )a ;
3272-
3273- npy_intp size0 = PyArray_DIM (array , 0 );
3317+ npy_intp rows = PyArray_DIM (array , 0 );
32743318 // If 1D array, set size for axis 1 at 1, else use 2D array to get the size of axis 1
3275- npy_intp size1 = PyArray_NDIM (array ) == 1 ? 1 : PyArray_DIM (array , 1 );
3276- return Py_BuildValue ( "nn" , size0 , size1 );
3319+ npy_intp cols = PyArray_NDIM (array ) == 1 ? 1 : PyArray_DIM (array , 1 );
3320+ return AK_build_pair_ssize_t ( rows , cols );
32773321}
32783322
32793323// Reshape if necessary a flat ndim 1 array into a 2D array with one columns and rows of length.
@@ -4240,7 +4284,7 @@ AK_BI_item(BlockIndexObject* self, Py_ssize_t i) {
42404284 return NULL ;
42414285 }
42424286 BlockIndexRecord * biri = & self -> bir [i ];
4243- return Py_BuildValue ( "nn" , biri -> block , biri -> column ); // maybe NULL
4287+ return AK_build_pair_ssize_t ( biri -> block , biri -> column ); // may be NULL
42444288}
42454289
42464290//------------------------------------------------------------------------------
@@ -4788,7 +4832,7 @@ BIIterContiguous_iternext(BIIterContiguousObject *self)
47884832 }
47894833 // no more pairs, return previous slice_start, flag for end on next call
47904834 self -> next_block = -2 ;
4791- return Py_BuildValue ( "nN" , // N steals ref
4835+ return AK_build_pair_ssize_t_slice ( // steals ref
47924836 self -> last_block ,
47934837 AK_build_slice_inclusive (slice_start ,
47944838 self -> last_column ,
@@ -4813,7 +4857,7 @@ BIIterContiguous_iternext(BIIterContiguousObject *self)
48134857 }
48144858 self -> next_block = block ;
48154859 self -> next_column = column ;
4816- return Py_BuildValue ( "nN" , // N steals ref
4860+ return AK_build_pair_ssize_t_slice ( // steals ref
48174861 self -> last_block ,
48184862 AK_build_slice_inclusive (slice_start ,
48194863 self -> last_column ,
@@ -5211,7 +5255,7 @@ BlockIndex_to_list(BlockIndexObject *self, PyObject *Py_UNUSED(unused)) {
52115255 BlockIndexRecord * bir = self -> bir ;
52125256
52135257 for (Py_ssize_t i = 0 ; i < self -> bir_count ; i ++ ) {
5214- PyObject * item = Py_BuildValue ( "nn" , bir [i ].block , bir [i ].column );
5258+ PyObject * item = AK_build_pair_ssize_t ( bir [i ].block , bir [i ].column );
52155259 if (item == NULL ) {
52165260 Py_DECREF (list );
52175261 return NULL ;
@@ -5248,17 +5292,14 @@ BlockIndex_getstate(BlockIndexObject *self) {
52485292 return NULL ;
52495293 }
52505294 PyObject * dt = self -> dtype == NULL ? Py_None : (PyObject * ) self -> dtype ;
5251-
52525295 // state might be NULL on failure; assume exception set
5253- PyObject * state = Py_BuildValue ("nnnnOO" ,
5296+ PyObject * state = Py_BuildValue ("nnnnNO" , // use N to steal ref of bytes
52545297 self -> block_count ,
52555298 self -> row_count ,
52565299 self -> bir_count ,
52575300 self -> bir_capacity ,
52585301 bi ,
52595302 dt ); // increfs passed object
5260-
5261- Py_DECREF (bi );
52625303 return state ;
52635304}
52645305
@@ -5283,7 +5324,7 @@ BlockIndex_shape_getter(BlockIndexObject *self, void* Py_UNUSED(closure))
52835324{
52845325 if (self -> shape == NULL || self -> shape_recache ) {
52855326 Py_XDECREF (self -> shape ); // get rid of old if it exists
5286- self -> shape = Py_BuildValue ( "nn" , self -> row_count , self -> bir_count ); // new ref
5327+ self -> shape = AK_build_pair_ssize_t ( self -> row_count , self -> bir_count );
52875328 }
52885329 // shape is not null and shape_recache is false
52895330 Py_INCREF (self -> shape ); // for caller
0 commit comments