MCPcopy Create free account
hub / github.com/numpy/numpy / _parse_axes_arg

Function _parse_axes_arg

numpy/core/src/umath/ufunc_object.c:1810–1947  ·  view source on GitHub ↗

* Interpret a possible axes keyword argument, using it to fill the remap_axis * array which maps default to actual axes for each operand, indexed as * as remap_axis[iop][iaxis]. The default axis order has first all broadcast * axes and then the core axes the gufunc operates on. * * Returns 0 on success, and -1 on failure */

Source from the content-addressed store, hash-verified

1808 * Returns 0 on success, and -1 on failure
1809 */
1810static int
1811_parse_axes_arg(PyUFuncObject *ufunc, int op_core_num_dims[], PyObject *axes,
1812 PyArrayObject **op, int broadcast_ndim, int **remap_axis) {
1813 static PyObject *AxisError_cls = NULL;
1814
1815 int nin = ufunc->nin;
1816 int nop = ufunc->nargs;
1817 int iop, list_size;
1818
1819 if (!PyList_Check(axes)) {
1820 PyErr_SetString(PyExc_TypeError, "axes should be a list.");
1821 return -1;
1822 }
1823 list_size = PyList_Size(axes);
1824 if (list_size != nop) {
1825 if (list_size != nin || _has_output_coredims(ufunc)) {
1826 PyErr_Format(PyExc_ValueError,
1827 "axes should be a list with an entry for all "
1828 "%d inputs and outputs; entries for outputs can only "
1829 "be omitted if none of them has core axes.",
1830 nop);
1831 return -1;
1832 }
1833 for (iop = nin; iop < nop; iop++) {
1834 remap_axis[iop] = NULL;
1835 }
1836 }
1837 for (iop = 0; iop < list_size; ++iop) {
1838 int op_ndim, op_ncore, op_nbroadcast;
1839 int have_seen_axis[NPY_MAXDIMS] = {0};
1840 PyObject *op_axes_tuple, *axis_item;
1841 int axis, op_axis;
1842
1843 op_ncore = op_core_num_dims[iop];
1844 if (op[iop] != NULL) {
1845 op_ndim = PyArray_NDIM(op[iop]);
1846 op_nbroadcast = op_ndim - op_ncore;
1847 }
1848 else {
1849 op_nbroadcast = broadcast_ndim;
1850 op_ndim = broadcast_ndim + op_ncore;
1851 }
1852 /*
1853 * Get axes tuple for operand. If not a tuple already, make it one if
1854 * there is only one axis (its content is checked later).
1855 */
1856 op_axes_tuple = PyList_GET_ITEM(axes, iop);
1857 if (PyTuple_Check(op_axes_tuple)) {
1858 if (PyTuple_Size(op_axes_tuple) != op_ncore) {
1859 /* must have been a tuple with too many entries. */
1860 npy_cache_import(
1861 "numpy.exceptions", "AxisError", &AxisError_cls);
1862 if (AxisError_cls == NULL) {
1863 return -1;
1864 }
1865 PyErr_Format(AxisError_cls,
1866 "%s: operand %d has %d core dimensions, "
1867 "but %zd dimensions are specified by axes tuple.",

Callers 1

Calls 6

_has_output_coredimsFunction · 0.85
PyArray_NDIMFunction · 0.85
npy_cache_importFunction · 0.85
ufunc_get_name_cstrFunction · 0.85
PyArray_PyIntAsIntFunction · 0.85
check_and_adjust_axisFunction · 0.85

Tested by

no test coverage detected