Repository: scipy/scipy
File: scipy/sparse/_compressed.py (Python)

Code before:
            if res.format != 'csr':
                res = res.tocsr()
            res = res.reshape(new_shape)
        return res

    def diagonal(self, k=0):
        M, N = self._swap(self.shape)
        k, _ = self._swap((k, -k))

        if k <= -M or k >= N:
            return np.empty(0, dtype=self.data.dtype)
        y = np.empty(min(M + min(k, 0), N - max(k, 0)), dtype=upcast(self.dtype))
        csr_diagonal(k, M, N, self.indptr, self.indices, self.data, y)
        return y

    diagonal.__doc__ = _spbase.diagonal.__doc__

    #####################
    # Reduce operations #
    #####################

    def sum(self, axis=None, dtype=None, out=None):
        """Sum the array/matrix over the given axis.  If the axis is None, sum
        over both rows and columns, returning a scalar.
        """
        # The _spbase base class already does axis=None and minor axis efficiently
        # so we only do the case axis=major axis
        if (self.ndim == 2 and not hasattr(self, 'blocksize') and
                axis in self._swap(((1, -1), (0, -2)))[0]):
            # faster than multiplication for large major axis in CSC/CSR
            
            if dtype is not None:
                # Cast upfront to use dtype as accumulator type (NumPy semantics)
                self_to_reduce = self.astype(dtype, copy=False)
                res_dtype = dtype
            else:
                self_to_reduce = self
                res_dtype = get_sum_dtype(self.dtype)
            
            # Fast path: reduce along minor axis
            ret = np.zeros(len(self_to_reduce.indptr) - 1, dtype=res_dtype)
            major_index, value = self_to_reduce._minor_reduce(np.add)
            ret[major_index] = value
            ret = self_to_reduce._ascontainer(ret)
            if axis % 2 == 1:
                ret = ret.T

            if out is not None:
                out[...] = ret
                return out
            return ret

Review comment (suggestion):
This quick piece of code handles the case where `axis=minor`, right? That is, when CSR gets `axis=1` or CSC gets `axis=0`. So I think the original comments are correct. 

I also don't think we should state "use dtype as accumulator type" in the comment on line 503 because we don't actually have an accumulator. We are just converting the dtype of the input array. 

Code after:
            if res.format != 'csr':
                res = res.tocsr()
            res = res.reshape(new_shape)
        return res

    def diagonal(self, k=0):
        M, N = self._swap(self.shape)
        k, _ = self._swap((k, -k))

        if k <= -M or k >= N:
            return np.empty(0, dtype=self.data.dtype)
        y = np.empty(min(M + min(k, 0), N - max(k, 0)), dtype=upcast(self.dtype))
        csr_diagonal(k, M, N, self.indptr, self.indices, self.data, y)
        return y

    diagonal.__doc__ = _spbase.diagonal.__doc__

    #####################
    # Reduce operations #
    #####################

    def sum(self, axis=None, dtype=None, out=None):
        """Sum the array/matrix over the given axis.  If the axis is None, sum
        over both rows and columns, returning a scalar.
        """
        # The _spbase base class already does axis=None and major axis efficiently
        # so we only do the case axis= minor axis
        if (self.ndim == 2 and not hasattr(self, 'blocksize') and
                axis in self._swap(((1, -1), (0, -2)))[0]):
            # faster than multiplication for large minor axis in CSC/CSR
            
            res_dtype = get_sum_dtype(self.dtype) if dtype is None else dtype
            self_to_reduce = self.astype(res_dtype, copy=False)
            
            # Fast path: reduce along minor axis
            ret = np.zeros(len(self_to_reduce.indptr) - 1, dtype=res_dtype)
            major_index, value = self_to_reduce._minor_reduce(np.add)
            ret[major_index] = value
            ret = self_to_reduce._ascontainer(ret)
            if axis % 2 == 1:
                ret = ret.T

            return ret.sum(axis=(), dtype=res_dtype, out=out)
        else:
            return _spbase.sum(self, axis=axis, dtype=dtype, out=out)

    sum.__doc__ = _spbase.sum.__doc__

    def _minor_reduce(self, ufunc, data=None):
        """Reduce nonzeros with a ufunc over the minor axis when non-empty