* Converts a list of subscripts to a string. * * Returns -1 on error, the number of characters placed in subscripts * otherwise. */
| 2813 | * otherwise. |
| 2814 | */ |
| 2815 | static int |
| 2816 | einsum_list_to_subscripts(PyObject *obj, char *subscripts, int subsize) |
| 2817 | { |
| 2818 | int ellipsis = 0, subindex = 0; |
| 2819 | npy_intp i, size; |
| 2820 | PyObject *item; |
| 2821 | |
| 2822 | obj = PySequence_Fast(obj, "the subscripts for each operand must " |
| 2823 | "be a list or a tuple"); |
| 2824 | if (obj == NULL) { |
| 2825 | return -1; |
| 2826 | } |
| 2827 | size = PySequence_Size(obj); |
| 2828 | |
| 2829 | for (i = 0; i < size; ++i) { |
| 2830 | item = PySequence_Fast_GET_ITEM(obj, i); |
| 2831 | /* Ellipsis */ |
| 2832 | if (item == Py_Ellipsis) { |
| 2833 | if (ellipsis) { |
| 2834 | PyErr_SetString(PyExc_ValueError, |
| 2835 | "each subscripts list may have only one ellipsis"); |
| 2836 | Py_DECREF(obj); |
| 2837 | return -1; |
| 2838 | } |
| 2839 | if (subindex + 3 >= subsize) { |
| 2840 | PyErr_SetString(PyExc_ValueError, |
| 2841 | "subscripts list is too long"); |
| 2842 | Py_DECREF(obj); |
| 2843 | return -1; |
| 2844 | } |
| 2845 | subscripts[subindex++] = '.'; |
| 2846 | subscripts[subindex++] = '.'; |
| 2847 | subscripts[subindex++] = '.'; |
| 2848 | ellipsis = 1; |
| 2849 | } |
| 2850 | /* Subscript */ |
| 2851 | else { |
| 2852 | npy_intp s = PyArray_PyIntAsIntp(item); |
| 2853 | /* Invalid */ |
| 2854 | if (error_converting(s)) { |
| 2855 | PyErr_SetString(PyExc_TypeError, |
| 2856 | "each subscript must be either an integer " |
| 2857 | "or an ellipsis"); |
| 2858 | Py_DECREF(obj); |
| 2859 | return -1; |
| 2860 | } |
| 2861 | npy_bool bad_input = 0; |
| 2862 | |
| 2863 | if (subindex + 1 >= subsize) { |
| 2864 | PyErr_SetString(PyExc_ValueError, |
| 2865 | "subscripts list is too long"); |
| 2866 | Py_DECREF(obj); |
| 2867 | return -1; |
| 2868 | } |
| 2869 | |
| 2870 | if (s < 0) { |
| 2871 | bad_input = 1; |
| 2872 | } |
no test coverage detected