* Creates a struct dtype object from a Python dictionary. */
| 1040 | * Creates a struct dtype object from a Python dictionary. |
| 1041 | */ |
| 1042 | static PyArray_Descr * |
| 1043 | _convert_from_dict(PyObject *obj, int align) |
| 1044 | { |
| 1045 | PyObject *fields = PyDict_New(); |
| 1046 | if (fields == NULL) { |
| 1047 | return (PyArray_Descr *)PyErr_NoMemory(); |
| 1048 | } |
| 1049 | /* |
| 1050 | * Use PyMapping_GetItemString to support dictproxy objects as well. |
| 1051 | */ |
| 1052 | PyObject *names = PyMapping_GetItemString(obj, "names"); |
| 1053 | if (names == NULL) { |
| 1054 | Py_DECREF(fields); |
| 1055 | /* XXX should check this is a KeyError */ |
| 1056 | PyErr_Clear(); |
| 1057 | return _convert_from_field_dict(obj, align); |
| 1058 | } |
| 1059 | PyObject *descrs = PyMapping_GetItemString(obj, "formats"); |
| 1060 | if (descrs == NULL) { |
| 1061 | Py_DECREF(fields); |
| 1062 | /* XXX should check this is a KeyError */ |
| 1063 | PyErr_Clear(); |
| 1064 | Py_DECREF(names); |
| 1065 | return _convert_from_field_dict(obj, align); |
| 1066 | } |
| 1067 | int n = PyObject_Length(names); |
| 1068 | PyObject *offsets = PyMapping_GetItemString(obj, "offsets"); |
| 1069 | if (!offsets) { |
| 1070 | PyErr_Clear(); |
| 1071 | } |
| 1072 | PyObject *titles = PyMapping_GetItemString(obj, "titles"); |
| 1073 | if (!titles) { |
| 1074 | PyErr_Clear(); |
| 1075 | } |
| 1076 | |
| 1077 | if ((n > PyObject_Length(descrs)) |
| 1078 | || (offsets && (n > PyObject_Length(offsets))) |
| 1079 | || (titles && (n > PyObject_Length(titles)))) { |
| 1080 | PyErr_SetString(PyExc_ValueError, |
| 1081 | "'names', 'formats', 'offsets', and 'titles' dict " |
| 1082 | "entries must have the same length"); |
| 1083 | goto fail; |
| 1084 | } |
| 1085 | |
| 1086 | /* |
| 1087 | * If a property 'aligned' is in the dict, it overrides the align flag |
| 1088 | * to be True if it not already true. |
| 1089 | */ |
| 1090 | PyObject *tmp = PyMapping_GetItemString(obj, "aligned"); |
| 1091 | if (tmp == NULL) { |
| 1092 | PyErr_Clear(); |
| 1093 | } else { |
| 1094 | if (tmp == Py_True) { |
| 1095 | align = 1; |
| 1096 | } |
| 1097 | else if (tmp != Py_False) { |
| 1098 | Py_DECREF(tmp); |
| 1099 | PyErr_SetString(PyExc_ValueError, |
no test coverage detected