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

Code before:
        }
        if (s == 0) {
            n = n - 1;
        }
    }
    if (n == 0) {
        PyErr_SetString(PyExc_ValueError, "Expected at least one field name");
        return NULL;
    }
    PyObject *nameslist = PyTuple_New(n);
    if (!nameslist) {
        return NULL;
    }
    PyObject *fields = PyDict_New();
    if (!fields) {
        Py_DECREF(nameslist);
        return NULL;
    }

    /* Types with fields need the Python C API for field access */
    char dtypeflags = NPY_NEEDS_PYAPI;
    int maxalign = 1;
    int totalsize = 0;
    for (int i = 0; i < n; i++) {
        PyArray_Descr *conv = _convert_from_any(
                PyList_GET_ITEM(obj, i), align); // noqa: borrowed-ref - manual fix needed
        if (conv == NULL) {
            goto fail;
        }
        dtypeflags |= (conv->flags & NPY_FROM_FIELDS);
        if (align) {
            int _align = conv->alignment;
            if (_align > 1) {
                totalsize = NPY_NEXT_ALIGNED_OFFSET(totalsize, _align);
            }
            maxalign = PyArray_MAX(maxalign, _align);
        }
        PyObject *size_obj = PyLong_FromLong((long) totalsize);
        if (!size_obj) {
            Py_DECREF(conv);
            goto fail;
        }
        PyObject *tup = PyTuple_New(2);
        if (!tup) {
            Py_DECREF(size_obj);
            Py_DECREF(conv);
            goto fail;
        }
        PyTuple_SET_ITEM(tup, 0, (PyObject *)conv);
        PyTuple_SET_ITEM(tup, 1, size_obj);
        PyObject *key = PyUnicode_FromFormat("f%d", i);

Review comment (suggestion):
I think the uses in this function are actually fine. We create the `parsed` list inside NumPy in `_convert_from_commastring` on line 732 and it hasn't been exposed to other threads at this point.

Code after:
        }
        if (s == 0) {
            n = n - 1;
        }
    }
    if (n == 0) {
        PyErr_SetString(PyExc_ValueError, "Expected at least one field name");
        return NULL;
    }
    PyObject *nameslist = PyTuple_New(n);
    if (!nameslist) {
        return NULL;
    }
    PyObject *fields = PyDict_New();
    if (!fields) {
        Py_DECREF(nameslist);
        return NULL;
    }

    /* Types with fields need the Python C API for field access */
    char dtypeflags = NPY_NEEDS_PYAPI;
    int maxalign = 1;
    int totalsize = 0;
    for (int i = 0; i < n; i++) {
        PyArray_Descr *conv = _convert_from_any(
                PyList_GET_ITEM(obj, i), align); // noqa: borrowed-ref OK
        if (conv == NULL) {
            goto fail;
        }
        dtypeflags |= (conv->flags & NPY_FROM_FIELDS);
        if (align) {
            int _align = conv->alignment;
            if (_align > 1) {
                totalsize = NPY_NEXT_ALIGNED_OFFSET(totalsize, _align);
            }
            maxalign = PyArray_MAX(maxalign, _align);
        }
        PyObject *size_obj = PyLong_FromLong((long) totalsize);
        if (!size_obj) {
            Py_DECREF(conv);
            goto fail;
        }
        PyObject *tup = PyTuple_New(2);
        if (!tup) {
            Py_DECREF(size_obj);
            Py_DECREF(conv);
            goto fail;
        }
        PyTuple_SET_ITEM(tup, 0, (PyObject *)conv);
        PyTuple_SET_ITEM(tup, 1, size_obj);
        PyObject *key = PyUnicode_FromFormat("f%d", i);