numpy  2.0.0
src/multiarray/arrayobject.c File Reference
#include <Python.h>
#include "structmember.h"
#include "numpy/arrayobject.h"
#include "numpy/arrayscalars.h"
#include "npy_config.h"
#include "npy_pycompat.h"
#include "common.h"
#include "number.h"
#include "usertypes.h"
#include "arraytypes.h"
#include "scalartypes.h"
#include "arrayobject.h"
#include "ctors.h"
#include "methods.h"
#include "descriptor.h"
#include "iterators.h"
#include "mapping.h"
#include "getset.h"
#include "sequence.h"
#include "buffer.h"
#include "array_assign.h"
#include "alloc.h"
#include "mem_overlap.h"
#include "numpyos.h"

Defines

#define PY_SSIZE_T_CLEAN
#define NPY_NO_DEPRECATED_API   NPY_API_VERSION
#define _MULTIARRAYMODULE
#define CHECK_MEMORY
#define SMALL_STRING   2048
#define _rstrip_loop(CMP)
#define _reg_loop(CMP)

Functions

NPY_NO_EXPORT npy_intp PyArray_Size (PyObject *op)
NPY_NO_EXPORT int PyArray_SetUpdateIfCopyBase (PyArrayObject *arr, PyArrayObject *base)
NPY_NO_EXPORT int PyArray_SetBaseObject (PyArrayObject *arr, PyObject *obj)
NPY_NO_EXPORT int PyArray_CopyObject (PyArrayObject *dest, PyObject *src_object)
NPY_NO_EXPORT int PyArray_TypeNumFromName (char *str)
static void array_dealloc (PyArrayObject *self)
static char * extend (char **strp, Py_ssize_t n, Py_ssize_t *maxp)
static int dump_data (char **string, Py_ssize_t *n, Py_ssize_t *max_n, char *data, int nd, npy_intp *dimensions, npy_intp *strides, PyArrayObject *self)
NPY_NO_EXPORT void PyArray_DebugPrint (PyArrayObject *obj)
static PyObject * array_repr_builtin (PyArrayObject *self, int repr)
NPY_NO_EXPORT void PyArray_SetStringFunction (PyObject *op, int repr)
NPY_NO_EXPORT void PyArray_SetDatetimeParseFunction (PyObject *op)
static PyObject * array_repr (PyArrayObject *self)
static PyObject * array_str (PyArrayObject *self)
NPY_NO_EXPORT int PyArray_CompareUCS4 (npy_ucs4 *s1, npy_ucs4 *s2, size_t len)
NPY_NO_EXPORT int PyArray_CompareString (char *s1, char *s2, size_t len)
NPY_NO_EXPORT int array_might_be_written (PyArrayObject *obj)
NPY_NO_EXPORT int PyArray_FailUnlessWriteable (PyArrayObject *obj, const char *name)
static int _myunincmp (npy_ucs4 *s1, npy_ucs4 *s2, int len1, int len2)
static int _mystrncmp (char *s1, char *s2, int len1, int len2)
static void _rstripw (char *s, int n)
static void _unistripw (npy_ucs4 *s, int n)
static char * _char_copy_n_strip (char *original, char *temp, int nc)
static void _char_release (char *ptr, int nc)
static char * _uni_copy_n_strip (char *original, char *temp, int nc)
static void _uni_release (char *ptr, int nc)
static int _compare_strings (PyArrayObject *result, PyArrayMultiIterObject *multi, int cmp_op, void *func, int rstrip)
NPY_NO_EXPORT PyObject * _strings_richcompare (PyArrayObject *self, PyArrayObject *other, int cmp_op, int rstrip)
static PyObject * _void_compare (PyArrayObject *self, PyArrayObject *other, int cmp_op)
NPY_NO_EXPORT PyObject * array_richcompare (PyArrayObject *self, PyObject *other, int cmp_op)
NPY_NO_EXPORT int PyArray_ElementStrides (PyObject *obj)
NPY_NO_EXPORT npy_bool PyArray_CheckStrides (int elsize, int nd, npy_intp numbytes, npy_intp offset, npy_intp *dims, npy_intp *newstrides)
static PyObject * array_new (PyTypeObject *subtype, PyObject *args, PyObject *kwds)
static PyObject * array_iter (PyArrayObject *arr)
static PyObject * array_alloc (PyTypeObject *type, Py_ssize_t NPY_UNUSED(nitems))
static void array_free (PyObject *v)

Variables

static PyObject * PyArray_StrFunction = NULL
static PyObject * PyArray_ReprFunction = NULL
NPY_NO_EXPORT PyTypeObject PyArray_Type

Define Documentation

#define _reg_loop (   CMP)
Value:
{                                \
        while(size--) {                                 \
            val = compfunc((void *)iself->dataptr,       \
                          (void *)iother->dataptr,      \
                          N1, N2);                      \
            *dptr = (val CMP 0);                        \
            PyArray_ITER_NEXT(iself);                   \
            PyArray_ITER_NEXT(iother);                  \
            dptr += 1;                                  \
        }                                               \
    }
#define _rstrip_loop (   CMP)
Value:
{                                     \
        void *aptr, *bptr;                                      \
        char atemp[SMALL_STRING], btemp[SMALL_STRING];          \
        while(size--) {                                         \
            aptr = stripfunc(iself->dataptr, atemp, N1);        \
            if (!aptr) return -1;                               \
            bptr = stripfunc(iother->dataptr, btemp, N2);       \
            if (!bptr) {                                        \
                relfunc(aptr, N1);                              \
                return -1;                                      \
            }                                                   \
            val = compfunc(aptr, bptr, N1, N2);                  \
            *dptr = (val CMP 0);                                \
            PyArray_ITER_NEXT(iself);                           \
            PyArray_ITER_NEXT(iother);                          \
            dptr += 1;                                          \
            relfunc(aptr, N1);                                  \
            relfunc(bptr, N2);                                  \
        }                                                       \
    }
End borrowed from numarray

Referenced by _unistripw().

#define CHECK_MEMORY
Value:
do {                           \
        if (extend(string, *n, max_n) == NULL) {    \
            ret = -1;                               \
            goto end;                               \
        }                                           \
    } while (0)
#define NPY_NO_DEPRECATED_API   NPY_API_VERSION
#include <stdio.h>
#define SMALL_STRING   2048
Borrowed from Numarray

Referenced by _myunincmp().


Function Documentation

static char* _char_copy_n_strip ( char *  original,
char *  temp,
int  nc 
) [static]

Referenced by _mystrncmp().

static void _char_release ( char *  ptr,
int  nc 
) [static]

References PyArray_DESCR, and PyArray_TYPE.

Referenced by _mystrncmp().

static int _compare_strings ( PyArrayObject result,
PyArrayMultiIterObject multi,
int  cmp_op,
void *  func,
int  rstrip 
) [static]
static int _mystrncmp ( char *  s1,
char *  s2,
int  len1,
int  len2 
) [static]
Compare s1 and s2 which are not necessarily NULL-terminated. s1 is of length len1 s2 is of length len2 If they are NULL terminated, then stop comparison.

<

Only happens if NULLs are everywhere

References _char_copy_n_strip(), _char_release(), _myunincmp(), _uni_copy_n_strip(), _uni_release(), PyArrayIterObject_tag::ao, PyArrayMultiIterObject::iters, PyArray_DATA, PyArray_DESCR, and PyArrayMultiIterObject::size.

static int _myunincmp ( npy_ucs4 *  s1,
npy_ucs4 *  s2,
int  len1,
int  len2 
) [static]
This also handles possibly mis-aligned data
Compare s1 and s2 which are not necessarily NULL-terminated.
s1 is of length len1 s2 is of length len2 If they are NULL terminated, then stop comparison.

References SMALL_STRING.

Referenced by _mystrncmp().

static void _rstripw ( char *  s,
int  n 
) [static]

<

Never strip to length 0.
NPY_NO_EXPORT PyObject* _strings_richcompare ( PyArrayObject self,
PyArrayObject other,
int  cmp_op,
int  rstrip 
)
Cast arrays to a common type

<

define(NPY_PY3K)
Broad-cast the arrays to a common shape

References dimensions, PyArray_Dims::len, NPY_ANYORDER, NPY_BOOL, NPY_MAXDIMS, PyArray_Dims::ptr, PyArray_DIMS, PyArray_GenericReduceFunction(), PyArray_NDIM, and PyArray_Newshape().

static char* _uni_copy_n_strip ( char *  original,
char *  temp,
int  nc 
) [static]

Referenced by _mystrncmp().

static void _uni_release ( char *  ptr,
int  nc 
) [static]

Referenced by _mystrncmp().

static void _unistripw ( npy_ucs4 *  s,
int  n 
) [static]

<

Never strip to length 0.

References _rstrip_loop.

static PyObject* _void_compare ( PyArrayObject self,
PyArrayObject other,
int  cmp_op 
) [static]
VOID-type arrays can only be compared equal and not-equal in which case the fields are all compared by extracting the fields and testing one at a time... equality testing is performed using logical_ands on all the fields. in-equality testing is performed using logical_ors on all the fields.
VOID-type arrays without fields are compared for equality by comparing their memory at each location directly (using string-code).
If the field type has a non-trivial shape, additional dimensions will have been appended to <cite>a</cite> and <cite>b</cite>. In that case, reduce them using <cite>op</cite>.
If the type was multidimensional, collapse that part to 1-D
Reduce the extra dimension of <cite>temp</cite> using <cite>op</cite>
compare as a string. Assumes self and other have same descr->type
static PyObject* array_alloc ( PyTypeObject *  type,
Py_ssize_t   NPY_UNUSEDnitems 
) [static]
nitems will always be 0
static void array_dealloc ( PyArrayObject self) [static]
***************** end C-API functions *****************
array object functions
UPDATEIFCOPY means that base points to an array that should be updated with the contents of this array upon destruction. fa->base->flags must have been WRITEABLE (checked previously) and it was locked here thus, unlock it.

<

hold on to self in next call
<blockquote> Don't need to DECREF -- because we are deleting</blockquote>

System Message: WARNING/2 (<string>, line 2) Block quote ends without a blank line; unexpected unindent.
self already...
In any case base is pointing to something that we need to DECREF -- either a view or a buffer object
Free internal references if an Object array

<

hold on to self
Don't need to DECREF -- because we are deleting self already...
must match allocation in PyArray_NewFromDescr
static void array_free ( PyObject *  v) [static]
avoid same deallocator as PyBaseObject, see gentype_free
static PyObject* array_iter ( PyArrayObject arr) [static]
Call this from contexts where an array might be written to, but we have no way to tell. (E.g., when converting to a read-write buffer.)
2012-07-17, 1.7
Only warn once per array
static PyObject* array_new ( PyTypeObject *  subtype,
PyObject *  args,
PyObject *  kwds 
) [static]
Usually called with shape and type but can also be called with buffer, strides, and swapped info For now, let's just use this to create an empty, contiguous array of a specific type and shape.
place Py_None in object positions
buffer given -- use it
get writeable and aligned
static PyObject* array_repr ( PyArrayObject self) [static]
static PyObject* array_repr_builtin ( PyArrayObject self,
int  repr 
) [static]
max_n initial value is arbitrary, dump_data will extend it
NPY_NO_EXPORT PyObject* array_richcompare ( PyArrayObject self,
PyObject *  other,
int  cmp_op 
)
Special case for string arrays (which don't and currently can't have ufunc loops defined, so there's no point in trying).
Never mind, carry on, see what happens
Never mind, carry on, see what happens
If we reach this point, it means that we are not comparing string-to-string. It's possible that this will still work out, e.g. if the other array is an object array, then both will be cast to object or something? I don't know how that works actually, but it does, b/c this works:

System Message: ERROR/3 (<string>, line 6) Unexpected indentation.

<blockquote> l = ["a", "b"] assert np.array(l, dtype="S1") == np.array(l, dtype="O")</blockquote>

System Message: WARNING/2 (<string>, line 8) Block quote ends without a blank line; unexpected unindent.
So we fall through and see what happens.
See discussion in number.c
2013-07-25, 1.7
The ufunc does not support void/structured types, so these need to be handled specifically. Only a few cases are supported.
If not successful, indicate that the items cannot be compared this way.
2015-05-07, 1.10
2015-05-07, 1.10
If the comparison results in NULL, then the two array objects can not be compared together; indicate that
Comparisons should raise errors when element-wise comparison is not possible.
2015-05-14, 1.10
2013-07-25, 1.8
The ufunc does not support void/structured types, so these need to be handled specifically. Only a few cases are supported.
If not successful, indicate that the items cannot be compared this way.
2015-05-07, 1.10
2015-05-07, 1.10
Comparisons should raise errors when element-wise comparison is not possible.
2015-05-14, 1.10
static PyObject* array_str ( PyArrayObject self) [static]
static int dump_data ( char **  string,
Py_ssize_t *  n,
Py_ssize_t *  max_n,
char *  data,
int  nd,
npy_intp dimensions,
npy_intp strides,
PyArrayObject self 
) [static]
static char* extend ( char **  strp,
Py_ssize_t  n,
Py_ssize_t *  maxp 
) [static]
Extend string. On failure, returns NULL and leaves *strp alone. XXX we do this in multiple places; time for a string library?

System Message: WARNING/2 (<string>, line 1); backlink Inline emphasis start-string without end-string.

<

overflow
NPY_NO_EXPORT npy_bool PyArray_CheckStrides ( int  elsize,
int  nd,
npy_intp  numbytes,
npy_intp  offset,
npy_intp dims,
npy_intp newstrides 
)
This routine checks to see if newstrides (of length nd) will not ever be able to walk outside of the memory implied numbytes and offset.
The available memory is assumed to start at -offset and proceed to numbytes-offset. The strides are checked to ensure that accessing memory using striding will not try to reach beyond this memory for any of the axes.
If numbytes is 0 it will be calculated using the dimensions and element-size.
This function checks for walking beyond the beginning and right-end of the buffer and therefore works for any integer stride (positive or negative).
NPY_NO_EXPORT int PyArray_CompareString ( char *  s1,
char *  s2,
size_t  len 
)
NPY_NO_EXPORT int PyArray_CompareUCS4 ( npy_ucs4 *  s1,
npy_ucs4 *  s2,
size_t  len 
)
NPY_NO_EXPORT int PyArray_CopyObject ( PyArrayObject dest,
PyObject *  src_object 
)
Special code to mimic Numeric behavior for character arrays.
Get either an array object we can copy from, or its parameters if there isn't a convenient array available.
If it's not an array, either assign from a sequence or as a scalar
If the input is scalar
If there's one dest element and src is a Python scalar
TODO: switch to SAME_KIND casting
Otherwise use the dtype's setitem function
If there are more than enough dims, use AssignFromSequence because it can handle this style of broadcasting.
Otherwise convert to an array and do an array-based copy
If it's an array, do a move (handling possible overlapping data)

Referenced by array_subscript().

Prints the raw data of the ndarray in a form useful for debugging
low-level C issues.
NPY_NO_EXPORT int PyArray_ElementStrides ( PyObject *  obj)
NPY_NO_EXPORT int PyArray_FailUnlessWriteable ( PyArrayObject obj,
const char *  name 
)
This function does nothing if obj is writeable, and raises an exception

(and returns -1) if obj is not writeable. It may also do other house-keeping, such as issuing warnings on arrays which are transitioning to become views. Always call this function at some point before writing to an array.

'name' is a name for the array, used to give better error messages. Something like "assignment destination", "output array", or even just "array".

Referenced by _array_from_buffer_3118(), array_imag_get(), array_setfield(), array_subscript(), and map_increment().

NPY_NO_EXPORT int PyArray_SetBaseObject ( PyArrayObject arr,
PyObject *  obj 
)
Sets the 'base' attribute of the array. This steals a reference

to 'obj'.

Returns 0 on success, -1 on failure.

Allow the base to be set only once. Once the object which owns the data is set, it doesn't make sense to change it.
Don't allow infinite chains of views, always set the base to the first owner of the data. That is, either the first object which isn't an array, or the first object which owns its own data.
Propagate WARN_ON_WRITE through views.
If this array owns its own data, stop collapsing
If there's no base, stop collapsing
Stop the collapse new base when the would not be of the same type (i.e. different subclass).
Disallow circular references

Referenced by NpyIter_GetShape().

This function is scheduled to be removed <blockquote> TO BE REMOVED - NOT USED INTERNALLY.</blockquote>
NPY_NO_EXPORT void PyArray_SetStringFunction ( PyObject *  op,
int  repr 
)
Set the array print function to be a Python function.
Dispose of previous callback
Add a reference to new callback
Remember new callback
Dispose of previous callback
Add a reference to new callback
Remember new callback

References DEPRECATE_FUTUREWARNING, NPY_ARRAY_WARN_ON_WRITE, PyArray_BASE, PyArray_Check, PyArray_CLEARFLAGS(), and PyArray_FLAGS.

Precondition: 'arr' is a copy of 'base' (though possibly with different

strides, ordering, etc.). This function sets the UPDATEIFCOPY flag and the ->base pointer on 'arr', so that when 'arr' is destructed, it will copy any changes back to 'base'.

Steals a reference to 'base'.

Returns 0 on success, -1 on failure.

Any writes to 'arr' will magically turn into writes to 'base', so we should warn if necessary.
Unlike PyArray_SetBaseObject, we do not compress the chain of base references.
NPY_NO_EXPORT npy_intp PyArray_Size ( PyObject *  op)
Compute the size of an array (in number of items)
returns an Array-Scalar Object of the type of arr
from the given pointer to memory -- main Scalar creation function default new method calls this.
Ideally, here the descriptor would contain all the information needed.
So, that we simply need the data and the descriptor, and perhaps a flag
Given a string return the type-number for the data-type with that string as the type-object name. Returns NPY_NOTYPE without setting an error if no type can be found. Only works for user-defined data-types.

Variable Documentation

PyObject* PyArray_ReprFunction = NULL [static]
PyObject* PyArray_StrFunction = NULL [static]