# Buggy code
def get_arglist(I_type, T_type):
    """
    Generate argument list for calling the C++ function
    """
    args = []
    next_is_writeable = False
    j = 0
    for t in arg_spec:
        const = "" if next_is_writeable else "const "
        next_is_writeable = False
        if t == "*":
            next_is_writeable = True
            continue
        elif t == "i":
            args.append("*(%s*)a[%d]" % (const + I_type, j))
        elif t == "I":
            args.append("(%s*)a[%d]" % (const + I_type, j))
        elif t == "T":
            args.append("(%s*)a[%d]" % (const + T_type, j))
        elif t == "B":
            args.append("(npy_bool_wrapper*)a[%d]" % (j,))
        elif t == "V":
            if const:
                raise ValueError("'V' argument must be an output arg")
            args.append(
                "(std::vector<%s>*)a[%d]"
                % (
                    I_type,
                    j,
                )
            )
        elif t == "W":
            if const:
                raise ValueError("'W' argument must be an output arg")
            args.append(
                "(std::vector<%s>*)a[%d]"
                % (
                    T_type,
                    j,
                )
            )
        else:
            raise ValueError("Invalid spec character %r" % (t,))
        j += 1
    return ", ".join(args)


# Traceback (ValueError)
In [1]: import scipy.sparse
.. import numpy as np
.. X = scipy.sparse.csr_matrix(np.ones((2**16, 1)))
.. X
Out[1]:
# <65536x1 sparse matrix of type '<class 'numpy.float64'>'
#        with 65536 stored elements in Compressed Sparse Row format>

In [2]: (X*X[:2**15-1].T).toarray()
Out[2]:
array([[ 1.,  1.,  1., ...,  1.,  1.,  1.],
[ 1.,  1.,  1., ...,  1.,  1.,  1.],
[ 1.,  1.,  1., ...,  1.,  1.,  1.],
...,
[ 1.,  1.,  1., ...,  1.,  1.,  1.],
[ 1.,  1.,  1., ...,  1.,  1.,  1.],
[ 1.,  1.,  1., ...,  1.,  1.,  1.]])

In [3]: (X*X[:2**15].T).toarray()
ValueError                                Traceback (most recent call last)
<ipython-input-6-ee8192b524ea> in <module>()
----> 1 (X*X[:2**15].T).toarray()

/home/ec2-user/miniconda3/envs/test-env/lib/python3.6/site-packages/scipy/sparse/compressed.py in toarray(self, order, out)
918     def toarray(self, order=None, out=None):
919         """See the docstring for `spmatrix.toarray`."""
--> 920         return self.tocoo(copy=False).toarray(order=order, out=out)
921
922     ##############################################################

/home/ec2-user/miniconda3/envs/test-env/lib/python3.6/site-packages/scipy/sparse/coo.py in toarray(self, order, out)
256         M,N = self.shape
257         coo_todense(M, N, self.nnz, self.row, self.col, self.data,
--> 258                     B.ravel('A'), fortran)
259         return B
260

ValueError: could not convert integer scalar

# Fixed code
def get_arglist(I_type, T_type):
    """
    Generate argument list for calling the C++ function
    """
    args = []
    next_is_writeable = False
    j = 0
    for t in arg_spec:
        const = "" if next_is_writeable else "const "
        next_is_writeable = False
        if t == "*":
            next_is_writeable = True
            continue
        elif t == "i":
            args.append("*(%s*)a[%d]" % (const + I_type, j))
        elif t == "I":
            args.append("(%s*)a[%d]" % (const + I_type, j))
        elif t == "T":
            args.append("(%s*)a[%d]" % (const + T_type, j))
        elif t == "B":
            args.append("(npy_bool_wrapper*)a[%d]" % (j,))
        elif t == "V":
            if const:
                raise ValueError("'V' argument must be an output arg")
            args.append(
                "(std::vector<%s>*)a[%d]"
                % (
                    I_type,
                    j,
                )
            )
        elif t == "W":
            if const:
                raise ValueError("'W' argument must be an output arg")
            args.append(
                "(std::vector<%s>*)a[%d]"
                % (
                    T_type,
                    j,
                )
            )
        elif t == "l":
            args.append("*(%snpy_int64*)a[%d]" % (const, j))
        else:
            raise ValueError("Invalid spec character %r" % (t,))
        j += 1
    return ", ".join(args)