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 "npy_pycompat.h"
#include "numpy/npy_math.h"
#include "common.h"
#include "scalartypes.h"
#include "mapping.h"
#include "convert_datatype.h"
#include "_datetime.h"
#include "datetime_strings.h"

Defines

#define PY_SSIZE_T_CLEAN
#define NPY_NO_DEPRECATED_API   NPY_API_VERSION
#define _MULTIARRAYMODULE

Functions

NPY_NO_EXPORT PyObject * PyArray_CastToType (PyArrayObject *arr, PyArray_Descr *dtype, int is_f_order)
NPY_NO_EXPORT
PyArray_VectorUnaryFunc
PyArray_GetCastFunc (PyArray_Descr *descr, int type_num)
NPY_NO_EXPORT void PyArray_AdaptFlexibleDType (PyObject *data_obj, PyArray_Descr *data_dtype, PyArray_Descr **flex_dtype)
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)
static int can_cast_fields (PyObject *field1, PyObject *field2, NPY_CASTING casting)
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 can_cast_scalar_to (PyArray_Descr *scal_type, char *scal_data, PyArray_Descr *to, NPY_CASTING casting)
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)
static PyArray_Descrensure_dtype_nbo (PyArray_Descr *type)
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)

Variables

NPY_NO_EXPORT npy_intp REQUIRED_STR_LEN [] = {0, 3, 5, 10, 10, 20, 20, 20, 20}

Define Documentation

#define NPY_NO_DEPRECATED_API   NPY_API_VERSION

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;
static int can_cast_fields ( PyObject *  field1,
PyObject *  field2,
NPY_CASTING  casting 
) [static]
Compare two field dictionaries for castability.
Return 1 if 'field1' can be cast to 'field2' according to the rule 'casting', 0 if not.
Castabiliy of field dictionaries is defined recursively: 'field1' and 'field2' must have the same field names (possibly in different orders), and the corresponding field types must be castable according to the given casting rule.
Iterate over all the fields and compare for castability
Compare the dtype of the field for castability
NPY_NO_EXPORT npy_bool can_cast_scalar_to ( PyArray_Descr scal_type,
char *  scal_data,
PyArray_Descr to,
NPY_CASTING  casting 
)
Like PyArray_CanCastArrayTo
An aligned memory buffer large enough to hold any type
If the two dtypes are actually references to the same object or if casting type is forced unsafe then always OK.
If the scalar isn't a number, or the rule is stricter than NPY_SAFE_CASTING, use the straight type-based rules
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.
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, like datetime, is special cased to not fit in this hierarchy
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 PyArray_Descr* ensure_dtype_nbo ( PyArray_Descr type) [static]
Returns a new reference to type if it is already NBO, otherwise returns a copy converted to NBO.
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.
}

References npy_cdouble::imag, NPY_CFLOAT, and npy_cdouble::real.

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

Referenced by PyArray_DTypeFromObject(), and PyArray_DTypeFromObjectHelper().

NPY_NO_EXPORT void PyArray_AdaptFlexibleDType ( PyObject *  data_obj,
PyArray_Descr data_dtype,
PyArray_Descr **  flex_dtype 
)
This function calls Py_DECREF on flex_dtype, and replaces it with a new dtype that has been adapted based on the values in data_dtype and data_obj. If the flex_dtype is not flexible, it leaves it as is.
Usually, if data_obj is not an array, dtype should be the result given by the PyArray_GetArrayParamsFromObject function.
The data_obj may be NULL if just a dtype is is known for the source.
If *flex_dtype is NULL, returns immediately, without setting an exception. This basically assumes an error was already set previously.

System Message: WARNING/2 (<string>, line 10); backlink Inline emphasis start-string without end-string.
The current flexible dtypes include NPY_STRING, NPY_UNICODE, NPY_VOID, and NPY_DATETIME with generic units.
Flexible types with expandable size
First replace the flex dtype
Get a string-size estimate of the input. These are generallly the size needed, rounded up to a multiple of eight.
5 chars needed for cast to 'True' or 'False'
Element size should never be greater than 8 or less than 0 for integer type, but just in case...
Add character for sign symbol
Convert data array to list of objects since GetArrayParamsFromObject won't iterate over array.
We should never get here, but just in case someone adds a new flex dtype...
Flexible type with generic time unit that adapts
Detect the unit from the input's data

Referenced by get_nbo_datetime_to_string_transfer_function().

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 a scalar, check the value
Otherwise, use the standard rules

Referenced by array_diagonal(), PyUFunc_DefaultLegacyInnerLoopSelector(), and PyUFunc_ValidateCasting().

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 NPY_NOTYPE terminated C-int-array of types that the data-type can be cast to safely.

Referenced by _ctype_negative(), and PyArray_CanCastScalar().

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>

References _npy_smallest_type_of_kind_table, NPY_NSCALARKINDS, PyArray_CanCastSafely(), and PyArray_DescrFromType().

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
For datetime/timedelta, only treat casts moving towards more precision as safe.
If to_type_num is STRING or unicode see if the length is long enough to hold the stringified value of the object.
Boolean value cast to string type is 5 characters max for string 'False'.
Need at least 5 characters to convert from boolean to 'True' or 'False'.
Guard against unexpected integer size
Guard against unexpected integer size
Extra character needed for sign
Returns true if data of type 'from' may be cast to data of type
'to' according to the rule 'casting'.
Fast path for unsafe casts or basic types
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
`from' and `to' must have the same fields, and corresponding fields must be (recursively) castable.

System Message: WARNING/2 (<string>, line 1); backlink Inline interpreted text or phrase reference start-string without end-string.
System Message: WARNING/2 (<string>, line 1); backlink Inline interpreted text or phrase reference start-string without end-string.
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. Some kinds, like datetime, don't fit in the hierarchy, and are special cased as -1.
NPY_NO_CASTING or NPY_EQUIV_CASTING was specified

Referenced by PyUFunc_DefaultLegacyInnerLoopSelector(), and PyUFunc_ValidateCasting().

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
Must be broadcastable. This code is very similar to PyArray_CopyInto/PyArray_MoveInto except casting is done --- NPY_BUFSIZE is used as the size of the casting buffer.
Cast to an already created array.
CopyInto handles the casting now

References NPY_BOOL, NPY_DATETIME, NPY_OBJECT, NPY_TIMEDELTA, and NPY_VOID.

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

Referenced by fast_scalar_power().

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
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.
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.
If the array isn't a numeric scalar, just return the array's dtype.
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 <blockquote> Returns the type number the result should have, or NPY_NOTYPE on error.</blockquote>

Referenced by _pyarray_correlate(), and PyArray_CanCoerceScalar().

Get pointer to one of correct type for array
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/datetime/timedelta, so 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 except datetime/void
For strings and unicodes, take the larger size
Allow NUMBER -> STRING
Allow NUMBER -> UNICODE
BOOL can convert to almost anything
Allow NUMBER -> STRING
Allow NUMBER -> UNICODE
For types equivalent up to endianness, 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(), PyUFunc_MultiplicationTypeResolver(), and PyUFunc_SubtractionTypeResolver().

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
NPY_NO_EXPORT int PyArray_ValidType ( int  type)
Is the typenum valid?
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

Variable Documentation

NPY_NO_EXPORT npy_intp REQUIRED_STR_LEN[] = {0, 3, 5, 10, 10, 20, 20, 20, 20}
Required length of string when converting from unsigned integer type. Array index is integer size in bytes.

  • 3 chars needed for cast to max value of 255 or 127
  • 5 chars needed for cast to max value of 65535 or 32767
  • 10 chars needed for cast to max value of 4294967295 or 2147483647
  • 20 chars needed for cast to max value of 18446744073709551615
System Message: ERROR/3 (<string>, line 7) Unexpected indentation.

<blockquote> or 9223372036854775807</blockquote>