numpy 2.0.0
src/multiarray/descriptor.c File Reference
#include <Python.h>
#include "structmember.h"
#include "numpy/arrayobject.h"
#include "numpy/arrayscalars.h"
#include "npy_config.h"
#include "numpy/npy_3kcompat.h"
#include "common.h"

Defines

#define PY_SSIZE_T_CLEAN
#define _MULTIARRAYMODULE
#define NPY_NO_PREFIX
#define _chk_byteorder(arg)
#define _ARGSTR_   "(icOOOiiiO)"
#define _ARGSTR_   "(icOOOiii)"
#define _ARGSTR_   "(icOOOii)"
#define _ARGSTR_   "(icOOii)"
#define _ARGSTR_   "(cOOii)"

Functions

static PyArray_Descr_use_inherit (PyArray_Descr *type, PyObject *newobj, int *errflag)
NPY_NO_EXPORT PyArray_Descr_arraydescr_fromobj (PyObject *obj)
NPY_NO_EXPORT PyObject * array_set_typeDict (PyObject *NPY_UNUSED(ignored), PyObject *args)
static int _check_for_commastring (char *type, int len)
static int _check_for_datetime (char *type, int len)
static PyArray_Descr_convert_from_tuple (PyObject *obj)
static PyArray_Descr_convert_from_array_descr (PyObject *obj, int align)
static PyArray_Descr_convert_from_list (PyObject *obj, int align)
static NPY_DATETIMEUNIT _unit_from_str (char *base)
static int _convert_divisor_to_multiple (PyArray_DatetimeMetaData *meta)
static PyObject * _get_datetime_tuple_from_cobj (PyObject *cobj)
static PyObject * _convert_datetime_tuple_to_cobj (PyObject *tuple)
static PyArray_Descr_convert_from_datetime_tuple (PyObject *obj)
static PyArray_Descr_convert_from_datetime (PyObject *obj)
static PyArray_Descr_convert_from_commastring (PyObject *obj, int align)
static int _is_tuple_of_integers (PyObject *obj)
static PyArray_Descr_use_fields_dict (PyObject *obj, int align)
static PyArray_Descr_convert_from_dict (PyObject *obj, int align)
NPY_NO_EXPORT PyArray_DescrPyArray_DescrNewFromType (int type_num)
NPY_NO_EXPORT int PyArray_DescrConverter2 (PyObject *obj, PyArray_Descr **at)
NPY_NO_EXPORT int PyArray_DescrConverter (PyObject *obj, PyArray_Descr **at)
NPY_NO_EXPORT PyArray_DescrPyArray_DescrNew (PyArray_Descr *base)
static void arraydescr_dealloc (PyArray_Descr *self)
static PyObject * arraydescr_subdescr_get (PyArray_Descr *self)
static PyObject * _append_to_datetime_typestr (PyArray_Descr *self, PyObject *ret)
NPY_NO_EXPORT PyObject * arraydescr_protocol_typestr_get (PyArray_Descr *self)
static PyObject * arraydescr_typename_get (PyArray_Descr *self)
static PyObject * arraydescr_base_get (PyArray_Descr *self)
static PyObject * arraydescr_shape_get (PyArray_Descr *self)
NPY_NO_EXPORT PyObject * arraydescr_protocol_descr_get (PyArray_Descr *self)
static PyObject * arraydescr_isbuiltin_get (PyArray_Descr *self)
static int _arraydescr_isnative (PyArray_Descr *self)
static PyObject * arraydescr_isnative_get (PyArray_Descr *self)
static PyObject * arraydescr_fields_get (PyArray_Descr *self)
static PyObject * arraydescr_metadata_get (PyArray_Descr *self)
static PyObject * arraydescr_hasobject_get (PyArray_Descr *self)
static PyObject * arraydescr_names_get (PyArray_Descr *self)
static int arraydescr_names_set (PyArray_Descr *self, PyObject *val)
static int _invalid_metadata_check (PyObject *metadata)
static PyObject * arraydescr_new (PyTypeObject *NPY_UNUSED(subtype), PyObject *args, PyObject *kwds)
static PyObject * _get_pickleabletype_from_metadata (PyObject *metadata)
static PyObject * arraydescr_reduce (PyArray_Descr *self, PyObject *NPY_UNUSED(args))
static int _descr_find_object (PyArray_Descr *self)
static PyObject * arraydescr_setstate (PyArray_Descr *self, PyObject *args)
NPY_NO_EXPORT int PyArray_DescrAlignConverter (PyObject *obj, PyArray_Descr **at)
NPY_NO_EXPORT int PyArray_DescrAlignConverter2 (PyObject *obj, PyArray_Descr **at)
NPY_NO_EXPORT PyArray_DescrPyArray_DescrNewByteorder (PyArray_Descr *self, char newendian)
static PyObject * arraydescr_newbyteorder (PyArray_Descr *self, PyObject *args)
static PyObject * arraydescr_str (PyArray_Descr *self)
static PyObject * arraydescr_repr (PyArray_Descr *self)
static PyObject * arraydescr_richcompare (PyArray_Descr *self, PyObject *other, int cmp_op)
static Py_ssize_t descr_length (PyObject *self0)
static PyObject * descr_repeat (PyObject *self, Py_ssize_t length)
static PyObject * descr_subscript (PyArray_Descr *self, PyObject *op)

Variables

static PyObject * typeDict = NULL
NPY_NO_EXPORT char * _datetime_strings []
static NPY_DATETIMEUNIT _multiples_table [16][4]
static PyMemberDef arraydescr_members []
static PyGetSetDef arraydescr_getsets []
static PyMethodDef arraydescr_methods []
static PySequenceMethods descr_as_sequence
static PyMappingMethods descr_as_mapping
NPY_NO_EXPORT PyTypeObject PyArrayDescr_Type

Define Documentation

#define _ARGSTR_   "(icOOOiiiO)"
#define _ARGSTR_   "(icOOii)"
#define _ARGSTR_   "(cOOii)"
#define _ARGSTR_   "(icOOOii)"
#define _ARGSTR_   "(icOOOiii)"
#define _chk_byteorder (   arg)
Value:
(arg == '>' || arg == '<' ||        \
                             arg == '|' || arg == '=')
#define _MULTIARRAYMODULE
#define NPY_NO_PREFIX
#define PY_SSIZE_T_CLEAN

Function Documentation

static PyObject* _append_to_datetime_typestr ( PyArray_Descr self,
PyObject *  ret 
) [static]

This shouldn't happen

NPY_NO_EXPORT PyArray_Descr* _arraydescr_fromobj ( PyObject *  obj)

Understand basic ctypes
derived type
Understand ctypes structures --
bit-fields are not supported automatically aligns

static int _check_for_commastring ( char *  type,
int  len 
) [static]

Check for ints at start of string
Check for empty tuple
Check for presence of commas

static int _check_for_datetime ( char *  type,
int  len 
) [static]
static PyObject* _convert_datetime_tuple_to_cobj ( PyObject *  tuple) [static]

Assumes other objects are Python integers
FIXME There is no error handling here.

static int _convert_divisor_to_multiple ( PyArray_DatetimeMetaData meta) [static]
Translate divisors into multiples of smaller units
static PyArray_Descr* _convert_from_array_descr ( PyObject *  obj,
int  align 
) [static]
obj is a list. Each item is a tuple with
(field-name, data-type (either a list or a string), and an optional shape parameter).
field-name can be a string or a 2-tuple data-type can now be a list, string, or 2-tuple (string, metadata dictionary))

Insert name into nameslist
Process rest
Title can be "meta-data". Only insert it into the fields dictionary if it is a string and if it is not the same as the name.

static PyArray_Descr* _convert_from_commastring ( PyObject *  obj,
int  align 
) [static]
comma-separated string this is the format developed by the numarray records module and implemented by the format parser in that module this is an alternative implementation found in the _internal.py file patterned after that one -- the approach is to try to convert to a list (with tuples if any repeat information is present) and then call the _convert_from_list)

Referenced by PyArray_DescrConverter().

static PyArray_Descr* _convert_from_datetime ( PyObject *  obj) [static]
static PyArray_Descr* _convert_from_datetime_tuple ( PyObject *  obj) [static]

Create new timedelta or datetime dtype
Remove any reference to old metadata dictionary And create a new one for this new dtype
Failure in conversion
Assume this sets a new reference to dt_cobj

References _convert_from_list(), NPY_FAIL, PyArray_DescrConverter(), and PyBytes_Check.

static PyArray_Descr* _convert_from_dict ( PyObject *  obj,
int  align 
) [static]

Build item to insert (descr, offset, [title])
Insert into dictionary

static PyArray_Descr* _convert_from_list ( PyObject *  obj,
int  align 
) [static]
a list specifying a data-type can just be a list of formats. The names for the fields will default to f0, f1, f2, and so forth.

Ignore any empty string at end which _internal._commastring can produce
End ignore code.

Referenced by _convert_from_datetime_tuple().

static PyArray_Descr* _convert_from_tuple ( PyObject *  obj) [static]

try to interpret next item as a type
We get here if res was NULL but errflag wasn't set --- i.e. the conversion to a data-descr failed in _use_inherit
interpret next item as a typesize
Assume it's a metadata dictionary
interpret next item as shape (if it's a tuple) and reset the type to PyArray_VOID with a new fields attribute.
If (type, 1) was given, it is equivalent to type... or (type, ()) was given it is equivalent to type...
Force subarray->shape to always be a tuple

References _PyArray_Descr::elsize, error_converting, PyArray_DESCR_REPLACE, PyArray_PyIntAsInt(), PyArray_UNICODE, and _PyArray_Descr::type_num.

static int _descr_find_object ( PyArray_Descr self) [static]
returns 1 if this data-type has an object portion used when setting the state because hasobject is not stored.
static PyObject* _get_datetime_tuple_from_cobj ( PyObject *  cobj) [static]
static PyObject* _get_pickleabletype_from_metadata ( PyObject *  metadata) [static]
Return a tuple of (cleaned metadata dictionary, tuple with (str, num, events))
static int _invalid_metadata_check ( PyObject *  metadata) [static]

borrowed reference

Referenced by _arraydescr_isnative().

static int _is_tuple_of_integers ( PyObject *  obj) [static]

Referenced by _convert_from_datetime().

static NPY_DATETIMEUNIT _unit_from_str ( char *  base) [static]
static PyArray_Descr* _use_fields_dict ( PyObject *  obj,
int  align 
) [static]
a dictionary specifying a data-type must have at least two and up to four keys These must all be sequences of the same length.
can also have an additional key called "metadata" which can be any dictionary
"names" --- field names "formats" --- the data-type descriptors for the field.
Optional:
"offsets" --- integers indicating the offset into the record of the start of the field. if not given, then "consecutive offsets" will be assumed and placed in the dictionary.
"titles" --- Allows the use of an additional key for the fields dictionary.(if these are strings or unicode objects) or this can also be meta-data to be passed around with the field description.
Attribute-lookup-based field names merely has to query the fields dictionary of the data-descriptor. Any result present can be used to return the correct field.
So, the notion of what is a name and what is a title is really quite arbitrary.
What does distinguish a title, however, is that if it is not None, it will be placed at the end of the tuple inserted into the fields dictionary.and can therefore be used to carry meta-data around.
If the dictionary does not have "names" and "formats" entries, then it will be checked for conformity and used directly.
static PyArray_Descr * _use_inherit ( PyArray_Descr type,
PyObject *  newobj,
int *  errflag 
) [static]
A tuple type would be either (generic typeobject, typesize) or (fixed-length data-type, shape)
or (inheriting data-type, new-data-type) The new data-type must have the same itemsize as the inheriting data-type unless the latter is 0
Thus (int32, {'real':(int16,0),'imag',(int16,2)})
is one way to specify a descriptor that will give a['real'] and a['imag'] to an int32 array.
leave type reference alone

Referenced by _check_for_datetime().

NPY_NO_EXPORT PyObject* array_set_typeDict ( PyObject *  NPY_UNUSEDignored,
PyObject *  args 
)

Decrement old reference (if any)
Create an internal reference to it

static PyObject* arraydescr_base_get ( PyArray_Descr self) [static]
static void arraydescr_dealloc ( PyArray_Descr self) [static]
should never be called for builtin-types unless there is a reference-count problem
static PyObject* arraydescr_fields_get ( PyArray_Descr self) [static]

Referenced by _arraydescr_isnative().

static PyObject* arraydescr_hasobject_get ( PyArray_Descr self) [static]

Referenced by _arraydescr_isnative().

static PyObject* arraydescr_isbuiltin_get ( PyArray_Descr self) [static]
returns 1 for a builtin type and 2 for a user-defined data-type descriptor return 0 if neither (i.e. it's a copy of one)

References arraydescr_base_get(), arraydescr_protocol_descr_get(), arraydescr_protocol_typestr_get(), arraydescr_subdescr_get(), and arraydescr_typename_get().

Referenced by _arraydescr_isnative().

static PyObject* arraydescr_isnative_get ( PyArray_Descr self) [static]
return Py_True if this data-type descriptor has native byteorder if no fields are defined
or if all sub-fields have native-byteorder if fields are defined

Referenced by _arraydescr_isnative().

static PyObject* arraydescr_metadata_get ( PyArray_Descr self) [static]

Referenced by _arraydescr_isnative().

static PyObject* arraydescr_names_get ( PyArray_Descr self) [static]

References PyArray_DescrNew().

Referenced by _arraydescr_isnative().

static int arraydescr_names_set ( PyArray_Descr self,
PyObject *  val 
) [static]

Make sure all entries are strings
Update dictionary keys in fields
Borrowed references to item and new_key
Check for duplicates
Replace names
Replace fields

References _PyArray_Descr::metadata.

Referenced by _arraydescr_isnative().

static PyObject* arraydescr_new ( PyTypeObject *  NPY_UNUSEDsubtype,
PyObject *  args,
PyObject *  kwds 
) [static]

Get a new copy of it unless it's already a copy
We need to be sure to make a new copy of the data-type and any underlying dictionary
Make a copy of the metadata before merging with ometadata so that this data-type descriptor has it's own copy
Save a reference
Decrement the old reference
Update conv->metadata with anything new in metadata keyword, but do not over-write anything already there
Make a copy of the input dictionary

static PyObject* arraydescr_newbyteorder ( PyArray_Descr self,
PyObject *  args 
) [static]
NPY_NO_EXPORT PyObject* arraydescr_protocol_descr_get ( PyArray_Descr self)
NPY_NO_EXPORT PyObject* arraydescr_protocol_typestr_get ( PyArray_Descr self)
static PyObject* arraydescr_reduce ( PyArray_Descr self,
PyObject *  NPY_UNUSEDargs 
) [static]
return a tuple of (callable object, args, state).

version number of this pickle type. Increment if we need to change the format. Be sure to handle the old versions in arraydescr_setstate.
Now return the state which is at least byteorder, subarray, and fields
Handle CObject in NPY_METADATA_DTSTR key separately
newobj is a tuple of cleaned metadata dictionary and tuple of date_time info (str, num, den, events)

<

Use version 3 pickle format
for extended types it also includes elsize and alignment

static PyObject* arraydescr_repr ( PyArray_Descr self) [static]
static PyObject* arraydescr_richcompare ( PyArray_Descr self,
PyObject *  other,
int  cmp_op 
) [static]
static PyObject* arraydescr_setstate ( PyArray_Descr self,
PyObject *  args 
) [static]
state is at least byteorder, subarray, and fields but could include elsize and alignment for EXTENDED arrays

raise an error
If we ever need another pickle format, increment the version number. But we should still be able to handle the old versions.
Ensure that subarray[0] is an ArrayDescr and that subarray_shape obtained from subarray[1] is a tuple of integers.
We have a borrowed reference to metadata so no need to alter reference count

static PyObject* arraydescr_shape_get ( PyArray_Descr self) [static]

TODO
self->subarray->shape should always be a tuple, so this check should be unnecessary

Referenced by _arraydescr_isnative().

static PyObject* arraydescr_str ( PyArray_Descr self) [static]

TODO
self->subarray->shape should always be a tuple, so this check should be unnecessary

static PyObject* arraydescr_subdescr_get ( PyArray_Descr self) [static]
static PyObject* arraydescr_typename_get ( PyArray_Descr self) [static]

fixme: not reentrant

Referenced by arraydescr_isbuiltin_get().

static Py_ssize_t descr_length ( PyObject *  self0) [static]

*********** Implement Mapping Protocol ***********************

System Message: WARNING/2 (<string>, line 1)
Title overline too short.

   Implement Mapping Protocol ***************************
 
static PyObject* descr_repeat ( PyObject *  self,
Py_ssize_t  length 
) [static]
static PyObject* descr_subscript ( PyArray_Descr self,
PyObject *  op 
) [static]
NPY_NO_EXPORT int PyArray_DescrAlignConverter ( PyObject *  obj,
PyArray_Descr **  at 
)
Get type-descriptor from an object forcing alignment if possible

None goes to DEFAULT type.

any object with the .fields attribute and/or .itemsize attribute (if the

.fields attribute does not give the total size -- i.e. a partial record

naming). If itemsize is given it must be >= size computed from fields

The .fields attribute must return a convertible dictionary if present. Result inherits from PyArray_VOID.

NPY_NO_EXPORT int PyArray_DescrAlignConverter2 ( PyObject *  obj,
PyArray_Descr **  at 
)
Get type-descriptor from an object forcing alignment if possible
None goes to NULL.

References PY_FAIL, PyArray_CanCastTo(), PyArray_DescrCheck, PyArray_DescrConverter(), and PyArray_EquivTypes().

NPY_NO_EXPORT int PyArray_DescrConverter ( PyObject *  obj,
PyArray_Descr **  at 
)
Get typenum from an object -- None goes to PyArray_DEFAULT

This function takes a Python object representing a type and converts it to a the correct PyArray_Descr * structure to describe the type.

Many objects can be used to represent a data-type which in NumPy is quite a flexible concept.

This is the central code that converts Python objects to Type-descriptor objects that are used throughout numpy. new reference in *at

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

default
or a typecode string
Allow unicode format strings: convert to bytes
Check for a string typecode.
check for datetime format
check for commas present or first (or second) element a digit
When specifying length of UNICODE the number of characters is given to match the STRING interface. Each character can be more than one byte and itemsize must be the number of bytes.
Support for generic processing c4, i4, f8, etc...
or a tuple
or a list
or a dictionary
if (check_num == PyArray_NOTYPE) {

<blockquote class="first"> return PY_FAIL;</blockquote>

System Message: WARNING/2 (<string>, line 3) Block quote ends without a blank line; unexpected unindent.

}

Now check to see if the object is registered in typeDict

References _convert_from_commastring(), PY_FAIL, and PY_SUCCEED.

Referenced by _check_for_datetime(), _convert_from_datetime(), _convert_from_datetime_tuple(), array_empty(), array_nbytes_get(), array_zeros(), gentype_richcompare(), PyArray_DescrAlignConverter2(), and PyArray_DescrConverter2().

NPY_NO_EXPORT int PyArray_DescrConverter2 ( PyObject *  obj,
PyArray_Descr **  at 
)
Get typenum from an object -- None goes to NULL

References PY_FAIL, and PyArray_DescrConverter().

Referenced by array_set_string_function().

NPY_NO_EXPORT PyArray_Descr* PyArray_DescrNew ( PyArray_Descr base)
Array Descr Objects for dynamic types *
There are some statically-defined PyArray_Descr objects corresponding to the basic built-in types. These can and should be DECREF'd and INCREF'd as appropriate, anyway. If a mistake is made in reference counting, deallocation on these builtins will be attempted leading to problems.
This let's us deal with all PyArray_Descr objects using reference counting (regardless of whether they are statically or dynamically allocated).
base cannot be NULL

Don't copy PyObject_HEAD part

Referenced by _convert_from_datetime(), array_base_get(), and arraydescr_names_get().

NPY_NO_EXPORT PyArray_Descr* PyArray_DescrNewByteorder ( PyArray_Descr self,
char  newendian 
)
returns a copy of the PyArray_Descr structure with the byteorder

altered: no arguments: The byteorder is swapped (in all subfields as well) single argument: The byteorder is forced to the given state (in all subfields as well)

Valid states: ('big', '>') or ('little' or '<') ('native', or '=')

If a descr structure with | is encountered it's own byte-order is not changed but any fields are:

Deep bytorder change of a data-type descriptor * Leaves reference count of self unchanged --- does not DECREF self *

swap byteorder
make new dictionary with replaced PyArray_Descr Objects

Referenced by npyiter_apply_forced_iteration_order().

NPY_NO_EXPORT PyArray_Descr* PyArray_DescrNewFromType ( int  type_num)

References PyArray_VOID.


Variable Documentation

NPY_NO_EXPORT char* _datetime_strings[]
Initial value:
Exported as DATETIMEUNITS in multiarraymodule.c
Initial value:
 {
    {12, 52, 365},                            
    {NPY_FR_M, NPY_FR_W, NPY_FR_D},
    {4,  30, 720},                            
    {NPY_FR_W, NPY_FR_D, NPY_FR_h},
    {5,  7,  168, 10080},                     
    {NPY_FR_B, NPY_FR_D, NPY_FR_h, NPY_FR_m},
    {24, 1440, 86400},                        
    {NPY_FR_h, NPY_FR_m, NPY_FR_s},
    {24, 1440, 86400},                        
    {NPY_FR_h, NPY_FR_m, NPY_FR_s},
    {60, 3600},                               
    {NPY_FR_m, NPY_FR_s},
    {60, 60000},                              
    {NPY_FR_s, NPY_FR_ms},
    {1000, 1000000},                          
    {0, 0}
}
PyGetSetDef arraydescr_getsets[] [static]
PyMemberDef arraydescr_members[] [static]
Initial value:
 {
    {"type",
        T_OBJECT, offsetof(PyArray_Descr, typeobj), READONLY, NULL},
    {"kind",
        T_CHAR, offsetof(PyArray_Descr, kind), READONLY, NULL},
    {"char",
        T_CHAR, offsetof(PyArray_Descr, type), READONLY, NULL},
    {"num",
        T_INT, offsetof(PyArray_Descr, type_num), READONLY, NULL},
    {"byteorder",
        T_CHAR, offsetof(PyArray_Descr, byteorder), READONLY, NULL},
    {"itemsize",
        T_INT, offsetof(PyArray_Descr, elsize), READONLY, NULL},
    {"alignment",
        T_INT, offsetof(PyArray_Descr, alignment), READONLY, NULL},
    {"flags",
        T_INT, offsetof(PyArray_Descr, flags), READONLY, NULL},
    {NULL, 0, 0, 0, NULL},
}
we need to be careful about setting attributes because these objects are pointed to by arrays that depend on them for interpreting data. Currently no attributes of data-type objects can be set directly except names.
PyMethodDef arraydescr_methods[] [static]
Initial value:
 {
    
    {"__reduce__",
        (PyCFunction)arraydescr_reduce,
        METH_VARARGS, NULL},
    {"__setstate__",
        (PyCFunction)arraydescr_setstate,
        METH_VARARGS, NULL},
    {"newbyteorder",
        (PyCFunction)arraydescr_newbyteorder,
        METH_VARARGS, NULL},
    {NULL, NULL, 0, NULL}           
}
PyMappingMethods descr_as_mapping [static]
Initial value:
 {
    descr_length,                                
    (binaryfunc)descr_subscript,                 
    (objobjargproc)NULL,                         
}
PySequenceMethods descr_as_sequence [static]
Initial value:
 {
    descr_length,
    (binaryfunc)NULL,
    descr_repeat,
    NULL, NULL,
    NULL,                                        
    NULL,                                        
    0,                                           
    0,                                           
    0,                                           
}
NPY_NO_EXPORT PyTypeObject PyArrayDescr_Type
************ End of Mapping Protocol *************************

Referenced by _fill().

PyObject* typeDict = NULL [static]
Must be explicitly loaded