Update NumPy C API usage for 1.x and 2.0 compatibility
Numpy 2 replaces PyArray_* macros with functions, now accepting only PyObjectArray type arguments. We introduce casting from PyObject to PyArrayObject by wrapping relevant PyArray_* calls in new to_PyArrayObject util function. For assignment of 'base' attribute, PyArray_SetBaseObject is now used.
Related: #588
Edited by Anton Joubert