Repository: numpy/numpy
File: numpy/_core/src/multiarray/compiled_base.c (C)

Code before:
            if (lst == NULL) {
                /* Failed converting to NPY_INTP. */
                if (PyErr_ExceptionMatches(PyExc_TypeError)) {
                    PyErr_Clear();
                    /* Deprecated 2024-08-02, NumPy 2.1 */
                    if (DEPRECATE("Non-integer input passed to bincount. In a "
                                  "future version of NumPy, this will be an "
                                  "error. (Deprecated NumPy 2.1)") < 0) {
                        goto fail;
                    }
                }
                else {
                    /* Failure was not a TypeError. */
                    goto fail;
                }
            }
        }
        else {
            /* Got an empty list. */
            Py_DECREF(tmp1);
        }
    }

    if (lst == NULL) {
        flags = NPY_ARRAY_WRITEABLE | NPY_ARRAY_ALIGNED | NPY_ARRAY_C_CONTIGUOUS;
        if (PyArray_Size((PyObject *)list) &&
            PyArray_ISINTEGER((PyArrayObject *)list)) {
            flags = flags | NPY_ARRAY_FORCECAST;
        }
        PyArray_Descr* local_dtype = PyArray_DescrFromType(NPY_INTP);
        lst = (PyArrayObject *)PyArray_FromAny(list, local_dtype, 1, 1, flags, NULL);
        if (lst == NULL) {
            goto fail;
        }
    }
    len = PyArray_SIZE(lst);

    /*
     * This if/else if can be removed by changing the argspec above,
     */
    if (mlength == Py_None) {
        PyErr_SetString(PyExc_TypeError,
             "use 0 instead of None for minlength");
        goto fail;
    }
    else if (mlength != NULL) {
        minlength = PyArray_PyIntAsIntp(mlength);
        if (error_converting(minlength)) {
            goto fail;
        }
    }

Review comment (suggestion):
The deprecation makes this pretty messy, almost wondering if we should just finalize it...

In either case, I think the `PyArray_Size()` here ends up as an imprecise `PyArray_Check()` here (as it misses an empty `uint8` array for example)?

I am not quite sure that not setting force-cast in the non-array case won't finalize the deprecation (in small parts).
Since both paths use `PyArray_ContiguousFromAny`, I think that is fine.  Although, it may be that we are not relaxing allowing `uint64` for an array-like here i.e. something like:
```
class a:
    def __array__(self):
        return np.ones(10, dtype=np.uint64)
```

Code after:
            PyArray_Descr* local_dtype = PyArray_DescrFromType(NPY_INTP);
            lst = (PyArrayObject *)PyArray_FromAny((PyObject *)tmp1, local_dtype, 1, 1, flags, NULL);
            Py_DECREF(tmp1);
            if (lst == NULL) {
                /* Failed converting to NPY_INTP. */
                if (PyErr_ExceptionMatches(PyExc_TypeError)) {
                    PyErr_Clear();
                    /* Deprecated 2024-08-02, NumPy 2.1 */
                    if (DEPRECATE("Non-integer input passed to bincount. In a "
                                  "future version of NumPy, this will be an "
                                  "error. (Deprecated NumPy 2.1)") < 0) {
                        goto fail;
                    }
                }
                else {
                    /* Failure was not a TypeError. */
                    goto fail;
                }
            }
        }
        else {
            /* Got an empty list. */
            Py_DECREF(tmp1);
        }
    }

    if (lst == NULL) {
        int flags = NPY_ARRAY_WRITEABLE | NPY_ARRAY_ALIGNED | NPY_ARRAY_C_CONTIGUOUS;
        if (PyArray_Check((PyObject *)list) &&
            PyArray_ISINTEGER((PyArrayObject *)list)) {
            flags = flags | NPY_ARRAY_FORCECAST;
        }
        PyArray_Descr* local_dtype = PyArray_DescrFromType(NPY_INTP);
        lst = (PyArrayObject *)PyArray_FromAny(list, local_dtype, 1, 1, flags, NULL);
        if (lst == NULL) {
            goto fail;
        }
    }
    len = PyArray_SIZE(lst);

    /*
     * This if/else if can be removed by changing the argspec above,
     */
    if (mlength == Py_None) {
        PyErr_SetString(PyExc_TypeError,
             "use 0 instead of None for minlength");
        goto fail;
    }
    else if (mlength != NULL) {
        minlength = PyArray_PyIntAsIntp(mlength);
        if (error_converting(minlength)) {