numpy 2.0.0
src/multiarray/convert_datatype.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"
#include "scalartypes.h"
#include "mapping.h"
#include "convert_datatype.h"

Defines

#define PY_SSIZE_T_CLEAN
#define _MULTIARRAYMODULE
#define NPY_NO_PREFIX

Functions

NPY_NO_EXPORT PyObject * PyArray_CastToType (PyArrayObject *arr, PyArray_Descr *dtype, int fortran)
NPY_NO_EXPORT
PyArray_VectorUnaryFunc
PyArray_GetCastFunc (PyArray_Descr *descr, int type_num)
NPY_NO_EXPORT int PyArray_CastTo (PyArrayObject *out, PyArrayObject *mp)
NPY_NO_EXPORT int PyArray_CastAnyTo (PyArrayObject *out, PyArrayObject *mp)
NPY_NO_EXPORT int PyArray_CanCastSafely (int fromtype, int totype)
NPY_NO_EXPORT npy_bool PyArray_CanCastTo (PyArray_Descr *from, PyArray_Descr *to)
static int dtype_kind_to_ordering (char kind)
static int type_num_unsigned_to_signed (int type_num)
NPY_NO_EXPORT npy_bool PyArray_CanCastTypeTo (PyArray_Descr *from, PyArray_Descr *to, NPY_CASTING casting)
static int min_scalar_type_num (char *valueptr, int type_num, int *is_small_unsigned)
NPY_NO_EXPORT npy_bool PyArray_CanCastArrayTo (PyArrayObject *arr, PyArray_Descr *to, NPY_CASTING casting)
NPY_NO_EXPORT npy_bool PyArray_CanCastScalar (PyTypeObject *from, PyTypeObject *to)
static PyArray_Descrpromote_types (PyArray_Descr *type1, PyArray_Descr *type2, int is_small_unsigned1, int is_small_unsigned2)
NPY_NO_EXPORT PyArray_DescrPyArray_PromoteTypes (PyArray_Descr *type1, PyArray_Descr *type2)
NPY_NO_EXPORT PyArray_DescrPyArray_MinScalarType (PyArrayObject *arr)
static int dtype_kind_to_simplified_ordering (char kind)
NPY_NO_EXPORT PyArray_DescrPyArray_ResultType (npy_intp narrs, PyArrayObject **arr, npy_intp ndtypes, PyArray_Descr **dtypes)
NPY_NO_EXPORT int PyArray_ValidType (int type)
static int _check_object_rec (PyArray_Descr *descr)
NPY_NO_EXPORT char * PyArray_Zero (PyArrayObject *arr)
NPY_NO_EXPORT char * PyArray_One (PyArrayObject *arr)
NPY_NO_EXPORT int PyArray_ObjectType (PyObject *op, int minimum_type)
NPY_NO_EXPORT PyArrayObject ** PyArray_ConvertToCommonType (PyObject *op, int *retn)

Define Documentation

#define _MULTIARRAYMODULE
#define NPY_NO_PREFIX
#define PY_SSIZE_T_CLEAN

Function Documentation

static int _check_object_rec ( PyArray_Descr descr) [static]
Backward compatibility only
<blockquote> In both Zero and One</blockquote>

System Message: WARNING/2 (<string>, line 2) Block quote ends without a blank line; unexpected unindent.
You must free the memory once you are done with it using PyDataMem_FREE(ptr) or you create a memory leak*
If arr is an Object array you are getting a BORROWED reference to Zero or One. Do not DECREF. Please INCREF if you will be hanging on to it.
The memory for the ptr still must be freed in any case;

Referenced by PyArray_ResultType().

static int dtype_kind_to_ordering ( char  kind) [static]
Provides an ordering for the dtype 'kind' character codes

Boolean kind
Unsigned int kind
Signed int kind
Float kind
Complex kind
String kind
Unicode kind
Void kind
Object kind
Anything else - ideally shouldn't happen...

static int dtype_kind_to_simplified_ordering ( char  kind) [static]
Provides an ordering for the dtype 'kind' character codes, to help determine when to use the min_scalar_type function. This groups 'kind' into boolean, integer, floating point, and everything else.

Boolean kind
Unsigned int kind
Signed int kind
Float kind
Complex kind
Anything else

static int min_scalar_type_num ( char *  valueptr,
int  type_num,
int *  is_small_unsigned 
) [static]
CanCastArrayTo needs this function
NOTE: While this is unlikely to be a performance problem, if
it is it could be reverted to a simple positive/negative check as the previous system used.
The is_small_unsigned output flag indicates whether it's an unsigned integer, and would fit in a signed integer of the same bit size.

Float types aren't allowed to be demoted to integer types, but precision loss is allowed.
The code to demote complex to float is disabled for now, as forcing complex by adding 0j is probably desireable.
npy_cfloat value = *(npy_cfloat *)valueptr; if (value.imag == 0) {

System Message: WARNING/2 (<string>, line 2); backlink Inline emphasis start-string without end-string.
System Message: WARNING/2 (<string>, line 2); backlink Inline emphasis start-string without end-string.
System Message: ERROR/3 (<string>, line 4) Unexpected indentation.

<blockquote>

return min_scalar_type_num((char *)&value.real,
System Message: WARNING/2 (<string>, line 4); backlink Inline emphasis start-string without end-string.

NPY_FLOAT, is_small_unsigned);

</blockquote>

System Message: WARNING/2 (<string>, line 6) Block quote ends without a blank line; unexpected unindent.
}
if (value.imag == 0) {
return min_scalar_type_num((char *)&value.real,
System Message: WARNING/2 (<string>, line 3); backlink Inline emphasis start-string without end-string.

NPY_DOUBLE, is_small_unsigned);

System Message: WARNING/2 (<string>, line 5) Definition list ends without a blank line; unexpected unindent.
}
if (value.imag == 0) {
return min_scalar_type_num((char *)&value.real,
System Message: WARNING/2 (<string>, line 3); backlink Inline emphasis start-string without end-string.

NPY_LONGDOUBLE, is_small_unsigned);

System Message: WARNING/2 (<string>, line 5) Definition list ends without a blank line; unexpected unindent.
}

static PyArray_Descr* promote_types ( PyArray_Descr type1,
PyArray_Descr type2,
int  is_small_unsigned1,
int  is_small_unsigned2 
) [static]
Internal promote types function which handles unsigned integers which fit in same-sized signed integers specially.

Convert to the equivalent-sized signed integer
The table doesn't handle string/unicode/void, check the result
Convert to the equivalent-sized signed integer
The table doesn't handle string/unicode/void, check the result

NPY_NO_EXPORT npy_bool PyArray_CanCastArrayTo ( PyArrayObject arr,
PyArray_Descr to,
NPY_CASTING  casting 
)
Returns 1 if the array object may be cast to the given data type using
the casting rule, 0 otherwise. This differs from PyArray_CanCastTo in that it handles scalar arrays (0 dimensions) specially, by checking their value.

If it's not a scalar, use the standard rules
Otherwise, check the value
An aligned memory buffer large enough to hold any type
If we've got a small unsigned scalar, and the 'to' type is not unsigned, then make it signed to allow the value to be cast more appropriately.

Referenced by NpyIter_GetReadFlags().

NPY_NO_EXPORT int PyArray_CanCastSafely ( int  fromtype,
int  totype 
)
Check the type coercion rules.

Fast table lookup for small type numbers
Identity
Special-cases for some types
cancastto is a PyArray_NOTYPE terminated C-int-array of types that the data-type can be cast to safely.

Referenced by PyArray_ScalarKind().

NPY_NO_EXPORT npy_bool PyArray_CanCastScalar ( PyTypeObject *  from,
PyTypeObject *  to 
)
See if array scalars can be cast. <blockquote> TODO: For NumPy 2.0, add a NPY_CASTING parameter.</blockquote>
NPY_NO_EXPORT npy_bool PyArray_CanCastTo ( PyArray_Descr from,
PyArray_Descr to 
)
leaves reference count alone --- cannot be NULL <blockquote> PyArray_CanCastTypeTo is equivalent to this, but adds a 'casting' parameter.</blockquote>

Check String and Unicode more closely
TODO: If totype is STRING or unicode see if the length is long enough to hold the stringified value of the object.

Referenced by PyArray_DescrAlignConverter2().

NPY_NO_EXPORT npy_bool PyArray_CanCastTypeTo ( PyArray_Descr from,
PyArray_Descr to,
NPY_CASTING  casting 
)
Returns true if data of type 'from' may be cast to data of type
'to' according to the rule 'casting'.

If unsafe casts are allowed
Equivalent types can be cast with any value of 'casting'
For complicated case, use EquivTypes (for now)
Only NPY_NO_CASTING prevents byte order conversion
If safe or same-kind casts are allowed
Also allow casting from lower to higher kinds, according to the ordering provided by dtype_kind_to_ordering.
NPY_NO_CASTING or NPY_EQUIV_CASTING was specified

Referenced by array_set_string_function(), and NpyIter_GetReadFlags().

NPY_NO_EXPORT int PyArray_CastAnyTo ( PyArrayObject out,
PyArrayObject mp 
)
Cast to an already created array. Arrays don't have to be "broadcastable"
Only requirement is they have the same number of elements.

CopyAnyInto handles the casting now

References _npy_can_cast_safely_table.

NPY_NO_EXPORT int PyArray_CastTo ( PyArrayObject out,
PyArrayObject mp 
)
Must be broadcastable. This code is very similar to PyArray_CopyInto/PyArray_MoveInto except casting is done --- PyArray_BUFSIZE is used as the size of the casting buffer.
Cast to an already created array.

CopyInto handles the casting now

References PyArray_CopyAnyInto().

NPY_NO_EXPORT PyObject* PyArray_CastToType ( PyArrayObject arr,
PyArray_Descr dtype,
int  fortran 
)
For backward compatibility <blockquote>
Cast an array using typecode structure. steals reference to at --- cannot be NULL
This function always makes a copy of arr, even if the dtype doesn't change. </blockquote>

References PyArrayObject::dimensions, _PyArray_Descr::elsize, PyArrayObject::nd, NPY_STRING, NPY_UNICODE, NPY_VOID, Py_TYPE, PyArray_CopyInto(), PyArray_DESCR, PyArray_DESCR_REPLACE, PyArray_NewFromDescr(), and _PyArray_Descr::type_num.

Referenced by PyArray_PyIntAsIntp().

NPY_NO_EXPORT PyArrayObject** PyArray_ConvertToCommonType ( PyObject *  op,
int *  retn 
)
Raises error when len(op) == 0

all scalars
we need to upconvert to type that handles both intype and stype also don't forcecast the scalars.
Make sure all arrays are actual array objects.
forcecast scalars

NPY_NO_EXPORT PyArray_VectorUnaryFunc* PyArray_GetCastFunc ( PyArray_Descr descr,
int  type_num 
)
Get a cast function to cast from the input descriptor to the
output type_number (must be a registered data-type). Returns NULL if un-successful.

References PyArray_ArrFuncs::cast, and _PyArray_Descr::f.

NPY_NO_EXPORT PyArray_Descr* PyArray_MinScalarType ( PyArrayObject arr)
If arr is a scalar (has 0 dimensions) with a built-in number data type,
finds the smallest type size/kind which can still represent its data. Otherwise, returns the array's data type.

An aligned memory buffer large enough to hold any type

NPY_NO_EXPORT int PyArray_ObjectType ( PyObject *  op,
int  minimum_type 
)
End deprecated
Return the typecode of the array a Python object would be converted to

Referenced by new_array_for_sum().

NPY_NO_EXPORT char* PyArray_One ( PyArrayObject arr)
Get pointer to one of correct type for array
NPY_NO_EXPORT PyArray_Descr* PyArray_PromoteTypes ( PyArray_Descr type1,
PyArray_Descr type2 
)
Produces the smallest size and lowest kind type to which both
input types can be cast.

If they're built-in types, use the promotion table
The table doesn't handle string/unicode/void, check the result
If one or both are user defined, calculate it
Promoted types are always native byte order
Promoted types are always native byte order
Convert the 'kind' char into a scalar kind
If both are scalars, there may be a promotion possible
Start with the larger scalar kind
If there is no larger type of this kind, try a larger kind
Use -1 to signal no promoted type found
If we found a type to which we can promote both, done!
Try the next larger type of this kind
BOOL can convert to anything
For strings and unicodes, take the larger size
Allow NUMBER -> STRING
Allow NUMBER -> UNICODE
BOOL can convert to anything
Allow NUMBER -> STRING
Allow NUMBER -> UNICODE
For equivalent types we can return either
TODO: Also combine fields, subarrays, strings, etc
printf("invalid type promotion: "); PyObject_Print(type1, stdout, 0); printf(" "); PyObject_Print(type2, stdout, 0); printf("n");

Referenced by PyArray_Clip().

NPY_NO_EXPORT PyArray_Descr* PyArray_ResultType ( npy_intp  narrs,
PyArrayObject **  arr,
npy_intp  ndtypes,
PyArray_Descr **  dtypes 
)
Produces the result type of a bunch of inputs, using the UFunc

type promotion rules. Use this function when you have a set of input arrays, and need to determine an output array dtype.

If all the inputs are scalars (have 0 dimensions) or the maximum "kind" of the scalars is greater than the maximum "kind" of the arrays, does a regular type promotion.

Otherwise, does a type promotion on the MinScalarType of all the inputs. Data types passed directly are treated as array types.

If there's just one type, pass it through
Determine if there are any scalars, and if so, whether the maximum "kind" of the scalars surpasses the maximum "kind" of the arrays
Compute the maximum "kinds" and whether everything is scalar
If the max scalar kind is bigger than the max array kind, finish computing the max array kind
Indicate whether to use the min_scalar_type function
Loop through all the types, promoting them
Combine it with the existing type
Only call promote if the types aren't the same dtype
Combine it with the existing type
Only call promote if the types aren't the same dtype
Get the min scalar type for the array
If it's a scalar, find the min scalar type. The function is expanded here so that we can flag whether we've got an unsigned integer which would fit an a signed integer of the same size, something not exposed in the public API.
An aligned memory buffer large enough to hold any type
Combine it with the existing type
If they point to the same type, don't call promote
Combine it with the existing type
Only call promote if the types aren't the same dtype

References _check_object_rec(), BEHAVED, PyArrayObject::descr, _PyArray_Descr::elsize, _PyArray_Descr::f, PyArrayObject::flags, PyArray_ISOBJECT, PyDataMem_FREE, PyDataMem_NEW, and PyArray_ArrFuncs::setitem.

Referenced by npyiter_apply_forced_iteration_order().

NPY_NO_EXPORT int PyArray_ValidType ( int  type)
Is the typenum valid?
NPY_NO_EXPORT char* PyArray_Zero ( PyArrayObject arr)
Get pointer to zero of correct type for array.
static int type_num_unsigned_to_signed ( int  type_num) [static]
Converts a type number from unsigned to signed