["python","numpy"]
numpy: formal definition of "array_like" objects?

In numpy, the constructors of many objects accept an "array_like" as first argument. Is there a definition of a such object, either as an abstract meta class, or documentation of the methods is should contain??
It turns out almost anything is technically an array-like. "Array-like" is more of a statement of how the input will be interpreted than a restriction on what the input can be; if a parameter is documented as array-like, NumPy will try to interpret it as an array. There is no formal definition of array-like beyond the nearly tautological one -- an array-like is any Python object that np.array can convert to an ndarray. To go beyond this, you'd need to study the source code. NPY_NO_EXPORT PyObject * PyArray_FromAny(PyObject *op, PyArray_Descr *newtype, int min_depth, int max_depth, int flags, PyObject *context) { /* * This is the main code to make a NumPy array from a Python * Object. It is called from many different places. */ PyArrayObject *arr = NULL, *ret; PyArray_Descr *dtype = NULL; int ndim = 0; npy_intp dims[NPY_MAXDIMS]; /* Get either the array or its parameters if it isn't an array */ if (PyArray_GetArrayParamsFromObject(op, newtype, 0, &dtype, &ndim, dims, &arr, context) < 0) { Py_XDECREF(newtype); return NULL; } ... Particularly interesting is PyArray_GetArrayParamsFromObject, whose comments enumerate the types of objects np.array expects: NPY_NO_EXPORT int PyArray_GetArrayParamsFromObject(PyObject *op, PyArray_Descr *requested_dtype, npy_bool writeable, PyArray_Descr **out_dtype, int *out_ndim, npy_intp *out_dims, PyArrayObject **out_arr, PyObject *context) { PyObject *tmp; /* If op is an array */ /* If op is a NumPy scalar */ /* If op is a Python scalar */ /* If op supports the PEP 3118 buffer interface */ /* If op supports the __array_struct__ or __array_interface__ interface */ /* * If op supplies the __array__ function. * The documentation says this should produce a copy, so * we skip this method if writeable is true, because the intent * of writeable is to modify the operand. * XXX: If the implementation is wrong, and/or if actual * usage requires this behave differently, * this should be changed! */ /* Try to treat op as a list of lists */ /* Anything can be viewed as an object, unless it needs to be writeable */ } So by studying the source code we can conclude an array-like is a NumPy array, or a NumPy scalar, or a Python scalar, or any object which supports the PEP 3118 buffer interface, or any object that supports the __array_struct__ or __array_interface__ interface, or any object that supplies the __array__ function, or any object that can be treated as a list of lists, or anything! If it doesn't fall under one of the other cases, it'll be treated as a 0-dimensional array of object dtype.