Skip to content

Commit 2fe6009

Browse files
authored
Merge pull request numpy#25954 from seberg/pyarray-pack
API: Expose `PyArray_Pack`
2 parents 0cbdbc2 + ad3524c commit 2fe6009

File tree

6 files changed

+33
-7
lines changed

6 files changed

+33
-7
lines changed

doc/source/reference/c-api/array.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,32 @@ and its sub-types).
3838
3939
Return the (builtin) typenumber for the elements of this array.
4040
41+
.. c:function:: int PyArray_Pack( \
42+
const PyArray_Descr *descr, void *item, const PyObject *value)
43+
44+
.. versionadded:: 2.0
45+
46+
Sets the memory location ``item`` of dtype ``descr`` to ``value``.
47+
48+
The function is equivalent to setting a single array element with a Python
49+
assignment. Returns 0 on success and -1 with an error set on failure.
50+
51+
.. note::
52+
If the ``descr`` has the :c:data:`NPY_NEEDS_INIT` flag set, the
53+
data must be valid or the memory zeroed.
54+
4155
.. c:function:: int PyArray_SETITEM( \
4256
PyArrayObject* arr, void* itemptr, PyObject* obj)
4357
4458
Convert obj and place it in the ndarray, *arr*, at the place
4559
pointed to by itemptr. Return -1 if an error occurs or 0 on
4660
success.
4761
62+
.. note::
63+
In general, prefer the use of :c:function:`PyArray_Pack` when
64+
handling arbitrary Python objects. Setitem is for example not able
65+
to handle arbitrary casts between different dtypes.
66+
4867
.. c:function:: void PyArray_ENABLEFLAGS(PyArrayObject* arr, int flags)
4968
5069
.. versionadded:: 1.7

doc/source/release/2.0.0-notes.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,12 @@ C API changes
347347

348348
(`gh-25789 <https://github.com/numpy/numpy/pull/25789>`__)
349349

350+
* NumPy now defines :c:function:`PyArray_Pack` to set an individual memory
351+
address. Unlike ``PyArray_SETITEM`` this function is equivalent to setting
352+
an individual array item and does not require a NumPy array input.
353+
354+
(`gh-25954 <https://github.com/numpy/numpy/pull/25954>`__)
355+
350356
* The ``->f`` slot has been removed from ``PyArray_Descr``.
351357
If you use this slot, replace accessing it with
352358
``PyDataType_GetArrFuncs`` (see its documentation and the

numpy/_core/code_generators/cversions.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,4 @@
7373
0x00000011 = ca1aebdad799358149567d9d93cbca09
7474

7575
# Version 18 (NumPy 2.0.0)
76-
0x00000012 = af4bcb877c1ce2e351681fe18bb8195d
76+
0x00000012 = 2b8f1f4da822491ff030b2b37dff07e3

numpy/_core/code_generators/numpy_api.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ def get_annotations():
103103

104104
multiarray_funcs_api = {
105105
'__unused_indices__': (
106-
[1, 4, 40, 41, 65, 66, 67, 68, 81, 82, 83,
106+
[1, 4, 40, 41, 66, 67, 68, 81, 82, 83,
107107
103, 115, 117, 122, 163, 164, 171, 173, 197,
108108
201, 202, 208, 219, 220, 221, 222, 223, 278,
109109
291, 293, 294, 295, 301]
@@ -135,7 +135,7 @@ def get_annotations():
135135
'PyArray_ScalarAsCtype': (62,),
136136
'PyArray_CastScalarToCtype': (63,),
137137
'PyArray_CastScalarDirect': (64,),
138-
# Unused slot 65, was `PyArray_ScalarFromObject`
138+
'PyArray_Pack': (65, MinVersion("2.0")),
139139
# Unused slot 66, was `PyArray_GetCastFunc`
140140
# Unused slot 67, was `PyArray_FromDims`
141141
# Unused slot 68, was `PyArray_FromDimsAndDataAndDescr`
@@ -399,10 +399,10 @@ def get_annotations():
399399
'PyArrayInitDTypeMeta_FromSpec': (362, MinVersion("2.0")),
400400
'PyArray_CommonDType': (363, MinVersion("2.0")),
401401
'PyArray_PromoteDTypeSequence': (364, MinVersion("2.0")),
402-
# End 2.0 API
403402
# The actual public API for this is the inline function
404403
# `PyDataType_GetArrFuncs` checks for the NumPy runtime version.
405404
'_PyDataType_GetArrFuncs': (365,),
405+
# End 2.0 API
406406
}
407407

408408
ufunc_types_api = {

numpy/_core/src/multiarray/array_coercion.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,8 @@ npy_cast_raw_scalar_item(
431431
}
432432

433433

434-
/**
434+
/*NUMPY_API
435+
**
435436
* Assign a single element in an array from a python value.
436437
*
437438
* The dtypes SETITEM should only be trusted to generally do the right
@@ -471,7 +472,7 @@ npy_cast_raw_scalar_item(
471472
* @return 0 on success -1 on failure.
472473
*/
473474
NPY_NO_EXPORT int
474-
PyArray_Pack(PyArray_Descr *descr, char *item, PyObject *value)
475+
PyArray_Pack(PyArray_Descr *descr, void *item, PyObject *value)
475476
{
476477
PyArrayObject_fields arr_fields = {
477478
.flags = NPY_ARRAY_WRITEABLE, /* assume array is not behaved. */

numpy/_core/src/multiarray/array_coercion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ npy_cast_raw_scalar_item(
2828
PyArray_Descr *to_descr, char *to_item);
2929

3030
NPY_NO_EXPORT int
31-
PyArray_Pack(PyArray_Descr *descr, char *item, PyObject *value);
31+
PyArray_Pack(PyArray_Descr *descr, void *item, PyObject *value);
3232

3333
NPY_NO_EXPORT PyArray_Descr *
3434
PyArray_AdaptDescriptorToArray(

0 commit comments

Comments
 (0)