NumPy 2.6.0 Release Notes#
Unreleased.
Highlights#
We’ll choose highlights for this release near the end of the release cycle.
New functions#
New function numpy.top_k#
A new function np.top_k(array, k, axis=..., mode=..., sorted=...)
was added, which returns the largest/smallest k values of an array
along a given axis.
(gh-31659)
New function numpy.minmax#
A new function np.minmax(a, axis=..., out=..., keepdims=..., initial=...,
where=...) was added, which returns a (min, max) tuple holding the
minimum and the maximum of an array along a given axis. It is equivalent to
(np.min(a, ...), np.max(a, ...)) but computes both in a single fused pass
over the data. For dtypes that support min/max but have no fused
minmax loop (such as the string DType and other user DTypes), it falls back
to two separate reductions. A masked-array counterpart np.ma.minmax was
also added, which simply returns (np.ma.min(a, ...), np.ma.max(a, ...)).
(gh-32231)
Deprecations#
numpy.linalg.lapack_lite is deprecated#
Importing numpy.linalg.lapack_lite is deprecated. The module is an
internal implementation detail of numpy.linalg and was never intended
as a public API. Users that need LAPACK or BLAS routines should use
scipy.linalg.lapack or scipy.linalg.blas instead.
(gh-32015)
Expired deprecations#
The deprecated
'full','f','economic', and'e'modes ofnumpy.linalg.qrhave been removed. These were deprecated in NumPy 1.8. Use'reduced'instead of'full'/'f', and'raw'instead of'economic'/'e'.(gh-31387)
The
numpy.typing.mypy_pluginmypy plugin (deprecated since NumPy 2.3) did not affect type-safety and has been removed in favor of platform- and type-checker-agnostic static typing.(gh-31931)
Compatibility notes#
numpy.insert out-of-bounds index detection#
numpy.insert now consistently raises IndexError for any
out-of-bounds index, including when out-of-bounds and in-bounds
indices are mixed in the same call. Previously such cases could
silently succeed or produce incorrect results.
(gh-31782)
ufunc.reduce on a multi-output ufunc now raises TypeError#
Calling reduce on a ufunc with more than one output
that does not register a reduction loop now raises a TypeError
instead of a ValueError. Of NumPy’s own ufuncs only numpy.divmod
is affected.
(gh-31816)
Casting and validation changes for fixed-width to variable-width string conversions#
Casts from fixed-width
numpy.bytes_andnumpy.str_arrays tonumpy.dtypes.StringDTypeare now considered “safe” rather than “same-kind”.These casts from
numpy.bytes_tonumpy.dtypes.StringDTypenow validate the bytes are valid UTF-8 and raise aUnicodeDecodeErrorotherwise.Casting a fixed-width numpy.void_ array containing invalid UTF-8 now triggers a
UnicodeDecodeErrorrather than aTypeError.
(gh-32095)
Python scalar promotion and casting#
numpy.concatenatewithaxis=Noneandnumpy.choosenow raiseOverflowErrorfor Python integers outside the result dtype’s range, instead of wrapping.Ufuncs,
numpy.copyto, andnumpy.concatenatenow enforce the same Python scalar restrictions forcasting="no"as forcasting="equiv".
See Cast safety of Python scalars for the detailed rules.
(gh-32497)
StringDType NaN-like inequality comparisons#
Inequality comparisons involving a NaN-like StringDType missing value now
return True, matching floating-point NaN behavior. Previously, both equality
and inequality returned False. Equality and ordered comparisons still
return False for NaN-like missing values.
Filtering with arr[arr != "excluded"] therefore retains NaN-like missing
values. To exclude them, use arr[(~np.isnan(arr)) & (arr != "excluded")].
(gh-32564)
C API changes#
NumPy DTypes are heap-allocated and can use PyType_FromMetaType#
Most of NumPy DType classes, except np.dtype itself, are now
heap-allocated types and downstream DTypes can now create their own
DType classes using PyType_FromMetaType.
DType authors using PyArrayInitDTypeMeta_FromSpec may notice this if the
DType has incorrect reference counting, since DTypes are no longer immortal.
In theory this also means that you cannot subclass abstract DTypes anymore
unless converting your DType to a heap-allocated type itself.
(gh-31364)
PyArray_StringDTypeObject is opaque under the abi3t stable ABI#
The PyArray_StringDTypeObject was accidentally exposed in NumPy
2.5 when targeting the free-threading-compatible stable ABI
(Py_TARGET_ABI3T). PyArray_StringDTypeObject is now an opaque
struct: extensions compiled that way cannot access its fields, since
the struct layout depends on the size of the object header. Any code
that accessed PyArray_StringDTypeObject fields in an abi3t build
would have crashed, so we are making this API change in a bugfix
release.
The NpyString allocator API remains usable by passing the
descriptor object pointer, e.g.
NpyString_acquire_allocator((PyArray_StringDTypeObject *)descr).
(gh-31771)
New mechanism to register reduction loops to ufuncs for multi-output reductions#
Ufuncs with more than one output can now support reduce
by registering a dedicated reduction loop (and, optionally, per-output
identities) on their ArrayMethod. The reduction returns one array per
output. See Adding a reduction loop to a ufunc for a worked example.
(gh-31816)
PyArray allocator helpers are now deprecated#
The following macro and C API helper functions for allocating data are now soft-deprecated:
NPY_USE_PYMEMPyArray_mallocPyArray_reallocPyArray_free
If you are using these in your extensions, we suggest migrating to use the Python Raw Memory Interface instead.
(gh-32334)
New Features#
Recognize ISO Fortran Environment kinds in F2Py#
This adds the int16, int32, and int64 integer kinds and
the real32 and real64 real kinds from the ISO Fortran
Environment module to F2Py.
(gh-28574)
New descending keyword argument for numpy.partition and numpy.argpartition#
Users can now pass the descending=True keyword argument to numpy.partition and
numpy.argpartition to partition and argpartition arrays in descending order.
NaN values, if present, are partitioned to the end of the array in both ascending and
descending sorts. This feature is available for all built-in dtypes except
void and generic.
(gh-31511)
DType partitioning and argpartitioning supports the ArrayMethod API#
User-defined dtypes can now implement custom partitioning and argpartitioning
using the ArrayMethod API in a fashion similar to sorting and argsorting.
These methods are used by numpy.partition and numpy.argpartition when called
with arrays of the user-defined dtype.
The partitioning and argpartitioning methods are registered by passing the
arraymethod specs that implement the operations to the PyUFunc_AddLoopsFromSpecs
function. See the ArrayMethod API documentation for details.
(gh-31614)
Add DLPack support to NumPy scalars#
scalar.__dlpack__ and scalar.__dlpack_device__ methods have been added
to NumPy scalars to allow exporting them to DLPack, similarly to ndarrays.
(gh-32029)
numpy.ma.unwrap has been added#
numpy.ma.unwrap is the mask-aware equivalent of numpy.unwrap. It skips over
the masked elements, computing each correction from the delta to the closest
preceding unmasked element rather than from the data underlying the mask, and
carries the mask through to the output.
(gh-32091)
Size inference when converting StringDType arrays to fixed-width strings#
Previously, converting a numpy.dtypes.StringDType array to a fixed-width
string dtype with an unspecified size, such as arr.astype(np.str_) or
np.array(arr, dtype="S"), raised a TypeError asking for an explicit
size. NumPy now inspects the array values and infers a size big enough to
store the widest entry without truncation, matching the existing behavior
when converting sequences of Python strings. Passing an explicit size still
truncates entries that do not fit.
(gh-32097)
Improvements#
(gh-32497)
StringDType comparisons now correctly handle embedded NULL bytes.
(gh-31662)
numpy.i0no longer returnsinffor large inputs such asnp.i0(713.0). The function now avoids intermediate overflow and returns the correct finite value.numpy.i0(np.inf) no longer triggers a spurious
RuntimeWarningdue to divide-by-zero in the implementation and returns np.inf rather than np.nan.(gh-32223)
np.copyto, np.full, np.where, np.concatenate with
axis=None, and np.choose now convert an exact Pythonstrscalar directly with the resolved dtype instead of through a fixed-width unicode intermediate, so a trailing null is no longer lost forStringDTypeorobject. For example,np.full(2, "x\0", dtype=np.dtypes.StringDType())[0]now gives"x\0"rather than"x".(gh-32356)
Casting a StringDType array to bool now correctly handles missing data that is a string. Previously it would treat an empty string as truthy and a non-empty string as falsey.
numpy.nonzeronow correctly classifies non-empty strings as nonzero.(gh-32418)
numpy.minimumandnumpy.maximumalong with theminandmaxreductions now correctly handle cases when one operand is a fixed-width string array and one operand is StringDType. These cases used to raise numpy._UFuncNoLoopError.(gh-32419)
Added support for dividing
timedelta64bybool.(gh-32555)
numpy.linalg.svdandnumpy.linalg.lstsqnow raise for inputs containing infinities instead of returning garbage results.Fixed hangs in
numpy.linalg.svdandnumpy.linalg.lstsqfor certain inputs containing infinities for recent versions of some LAPACK implementations.numpy.linalg.condnow handles non-finite inputs more consistently.(gh-32593)
np.show_runtime has display modes#
np.show_runtime now has a new optional parameter mode to help
customize the output.
(gh-26255)
numpy.common_type now raises a clear error for non-array input#
Passing a dtype or scalar type to numpy.common_type, such as
np.common_type(np.dtype("f4")), used to raise a confusing
AttributeError. It now raises a TypeError that points to
numpy.result_type and numpy.promote_types, which are the tools meant for
combining dtypes and scalar types.
(gh-30890)
nanmean, nanstd and nanvar no longer fail on read-only reductions#
These functions divide the running sum by the count in place, which assumed
the sum was writeable. When it was not they raised
ValueError: output array is read-only instead of returning a result and they
now allocate the output in that case, keeping the dtype the in-place divide
would have produced. This is what made np.nanmean, np.nanstd and
np.nanvar fail on a MaskedArray whose values are all masked, since
numpy.ma reduces that to the read-only np.ma.masked.
(gh-31069)
Structured dtypes now support larger field sizes#
It is now possible to construct structured data types with field sizes and offsets that exceed the size of a standard C integer. Arrays using these structured data types are now also possible to construct.
(gh-31332)
Object and StringDType array sorting supports descending=True#
np.sort and np.argsort with arrays of dtype object or StringDType
now support passing descending=True to sort in descending order. Objects that
compare as not equal to themselves (obj != obj), such as NaN-like objects,
and missing strings with a nan-like na_object are considered unordered and
are sorted to the end of the array, regardless of the value of descending.
Because np.partition and np.argpartition fall back to a full sort for
these dtypes, they now accept descending=True for them as well.
np.linspace no longer returns NaN for equal infinite endpoints#
np.linspace(np.inf, np.inf, N) (and -np.inf) now correctly returns
an array filled with inf instead of nan.
(gh-31620)
numpy.unwrap is now implemented as a generalized ufunc and preserves array subclasses#
The core of numpy.unwrap is now a generalized ufunc in C++ (signature (n),(),()->(n))
covering the floating point and signed integer dtypes while performing the operation
in a single pass without the intermediate arrays the previous Python implementation
had to allocate. As a result, numpy.unwrap now preserves the ndarray subclasses
rather than always returning a base ndarray.
(gh-31848)
DataSource accepts path-like local paths#
numpy.lib._datasource.DataSource and Repository now accept
os.PathLike local paths in the same places that accepted string paths.
This includes open, exists, and abspath methods, as well as the
module-level numpy.lib._datasource.open helper.
(gh-31906)
f2py handles platform-specific separators in --include-paths#
f2py --include-paths now splits include directories using the platform
path separator, fixing parsing of Windows paths containing drive letters.
(gh-31934)
StringDType partition accepts str separators#
np.strings.partition and np.strings.rpartition now accept a Python
str or fixed-width unicode separator when operating on StringDType
arrays. Previously the separator had to be a StringDType array itself.
(gh-32040)
Ensure F2Py defines required typedefs in generated C wrapper#
Ensure F2Py includes the typedefs required for kinds in the ISO C Binding module and the ISO Fortran Environment module in the generated C wrapper.
This also allows the int8 integer kind from the ISO Fortran
Environment module and the c_int8_t integer kind from the ISO C
Binding module to work.
(gh-32043)
Fixed-width string to StringDType casts are now safe and validated#
The casts from fixed-width numpy.bytes_ and numpy.str_ to
numpy.dtypes.StringDType are now marked “safe” rather than “same-kind”. We
also now validate that numpy.bytes_, numpy.void, and numpy.str_ arrays
contain valid UTF-8 before converting to numpy.dtypes.StringDType.
(gh-32095)
np.positive no longer raises _UfuncNoLoopError when called on boolean arrays#
np.positive and the unary + operator now register a loop for boolean arrays.
np.positive(np.array([True, False])) now returns [True, False]
(gh-32100)
Improved error for non-ASCII nditer flags#
numpy.nditer and numpy.nested_iters now read flag names from Python strings instead of encoding them to ASCII first. Flags containing non-ASCII characters used to raise UnicodeEncodeError, but now raise ValueError, which makes it consistent with the error given for other unrecognized flag names.
(gh-32232)
numpy.digitize preserves integer ordering for large values#
numpy.digitize no longer loses ordering information for large integer bin
edges that cannot be distinguished after conversion to float64.
(gh-32467)
StringDType hashing with NaN sentinels#
StringDType instances with equivalent floating-point NaN sentinels now
have equal hashes. Previously, distinct NaN objects could produce equal
dtype instances with different hashes, causing dictionary lookups and set
deduplication to fail.
(gh-32563)
StringDType missing-value handling#
NumPy’s array equality assertions now handle matching missing values in
StringDType arrays whose sentinel is a NumPy floating-point NaN, such as
numpy.float32("nan"). Previously, these assertions could incorrectly
report unequal arrays.
For numpy.unique, requesting indices, inverse indices, or counts now handles
NaN-like sentinels consistently: equal_nan=True groups missing entries,
while equal_nan=False keeps them separate. With return_index=True, the
index returned for grouped missing values now identifies their first occurrence.
Comparisons also correctly distinguish None-like missing values from empty
strings.
(gh-32564)
np.repeat accepts any integer dtype as repeats#
numpy.repeat now casts repeats with same-kind casting, like numpy.take.
Integer arrays such as uint64, or int64 on 32-bit platforms, no longer raise a TypeError.
(gh-32665)
np.put accepts any integer dtype as indices#
numpy.put now casts ind with same-kind casting, like numpy.take.
Integer arrays such as uint64, or int64 on 32-bit platforms, no longer raise a TypeError.
(gh-32666)
np.choose accepts any integer dtype as indices#
numpy.choose now casts a with same-kind casting, like numpy.take.
Integer arrays such as uint64, or int64 on 32-bit platforms, no longer raise a TypeError.
(gh-32667)
np.searchsorted accepts any integer dtype as sorter#
numpy.searchsorted now casts sorter with same-kind casting, like numpy.take.
Integer arrays such as uint64, or int64 on 32-bit platforms, no longer raise an error.
(gh-32668)
np.log no longer warns when propagating complex NaNs#
For complex inputs with at least one NaN component and no infinite component,
numpy.log now returns NaN + NaN j without emitting an invalid
floating-point warning.
(gh-32706)
logaddexp and logaddexp2 no longer warn for NaN inputs#
numpy.logaddexp and numpy.logaddexp2 now propagate NaN inputs without
emitting an invalid floating-point warning.
(gh-32733)
Performance improvements and changes#
numpy.isinis now much faster for largeStringDTypearrays.(gh-32693)
Faster ufunc calls through inner-loop caching#
Ufuncs implemented through the legacy ufunc API (which includes most ufuncs
provided by NumPy itself) now cache the selected inner-loop function instead
of looking it up on every call. This speeds up ufunc calls, most notably for
scalar and small-array inputs (roughly 10% faster). Note that as a
consequence, loops must be registered through the official API
(e.g. PyUFunc_ReplaceLoopBySignature); directly modifying the
functions member of a ufunc no longer takes effect.
(gh-31068)
Faster selected numpy.pad modes for zero-width axes#
numpy.pad is now faster for axes with pad width (0, 0) when using
mode="linear_ramp" or one of the statistic modes "maximum",
"mean", "median", and "minimum". These modes now skip unnecessary
mode-specific work for axes where no values are added.
(gh-31791)
Faster reductions on small arrays#
numpy.sum, numpy.prod, numpy.min, numpy.max, numpy.any,
and numpy.all are now faster for small arrays. This reduces the
Python-level overhead of calling these reductions, which is most noticeable
when the reduction itself is cheap.
(gh-31845)
Faster reductions for exact ndarrays#
numpy.sum, numpy.prod, numpy.min, numpy.max, numpy.amin, numpy.amax,
numpy.any, and numpy.all now avoid Python dispatch overhead for exact
numpy.ndarray inputs, reducing call times for benchmarked small-array
reductions by approximately 30%-50%. Subclasses and custom array types
continue to use the original __array_function__ dispatch path.
(gh-32041)
Faster method dispatch for np.take, np.argsort and similar functions#
The internal helpers that forward functions such as numpy.take,
numpy.reshape, numpy.transpose, numpy.argsort, numpy.argmax,
numpy.cumsum, numpy.round and numpy.searchsorted to the corresponding
ndarray method are now implemented in C. This reduces the Python-level call
overhead of about 25 dispatched functions, which is most noticeable for
small arrays (typically 5%-30% faster).
(gh-32165)
Better multithreaded scaling when using float constants on free-threaded Python#
On free-threaded builds, float constants such as np.pi and np.nan
are now immortal, which removes reference count contention between threads
using them concurrently.
(gh-32513)
Faster casts from fixed-width strings and faster str_ scalars#
Casting fixed-width string arrays (S and U dtypes) to numeric dtypes,
for example np.array(["1", "2"]).astype(int), is now 1.4-3x faster.
Creating numpy.str_ scalars, for instance when indexing or iterating over a
U array, is about 1.5x faster.
(gh-32550)
Faster standard normal sampling#
numpy.random.Generator.standard_normal now applies the sign of each variate
with a multiplication rather than a branch on a random bit, which the processor
cannot predict. This reduces the time per variate by roughly 30% to 40% on
x86-64, for both float64 and float32. aarch64 is unaffected, as
compilers already emit a conditional select there, and the legacy
numpy.random.RandomState normal variates are unaffected as they use a
different algorithm. The generated stream is unchanged.
(gh-32568)
Faster broadcasting in ufuncs#
Ufunc calls such as a + v with a.shape == (n, 3) and v.shape == (3,)
that include broadcasts now re-use iterator buffer more reliably.
This can lead to significant speed-ups for such operations.
(gh-32595)
Faster Laplace sampling#
numpy.random.Generator.laplace and numpy.random.RandomState.laplace now
select between the two halves of the inverse CDF without branching on an
unpredictable bit, and evaluate a single logarithm rather than one per branch.
This reduces the time per variate by roughly 20% on x86-64 and 40% on aarch64.
The generated stream is unchanged.
(gh-32601)
Descending sorts and partitions are now SIMD accelerated on x86#
numpy.sort, numpy.argsort, numpy.partition and numpy.argpartition
with descending=True no longer fall back to scalar code on x86, and now
use the same SIMD kernels as the ascending versions for most integer and
floating point dtypes. On AVX2 this is 2-9x faster than before.
(gh-32690)
Typing improvements and changes#
Generic numpy.object_ type#
The numpy.object_ scalar type is now a generic type, with its type parameter
representing the wrapped Python object, defaulting to Any if omitted.
(gh-32075)
Promotion-aware ufunc return types#
All ufuncs in the main namespace are now individually annotated, instead of sharing one
generic numpy.ufunc type. Their __call__, reduce, accumulate,
reduceat, outer, and at methods now follow NumPy’s promotion rules, so that
the output dtype is inferred instead of Any.
import numpy as np
import numpy.typing as npt
x: npt.NDArray[np.float32]
y: npt.NDArray[np.int16]
reveal_type(np.sqrt(y))
# before: npt.NDArray[Any]
# after: npt.NDArray[np.float32]
reveal_type(np.multiply(x, y))
# before: npt.NDArray[Any]
# after: npt.NDArray[np.float32]
This took 44 pull requests and over 20,000 lines of hand-written code, spread over 1,905 overloads.
(gh-32198)
numpy.random.Generator shape-typing#
The random sampling methods of numpy.random.Generator now use the size parameter
to infer the shape-type of the returned array.
rng = np.random.default_rng()
reveal_type(rng.normal(size=(2, 3)))
# before: ndarray[tuple[Any, ...], dtype[float64]]
# after: ndarray[tuple[int, int], dtype[float64]]
reveal_type(rng.dirichlet([0.3, 0.7], size=(2, 3))) # appends a dimension
# before: ndarray[tuple[Any, ...], dtype[float64]]
# after: ndarray[tuple[int, int, int], dtype[float64]]
(gh-32357)
numpy.linalg shape-typing#
The numpy.linalg functions now use the shape-types of their input(s) to infer the
shape-type of the returned array(s). Due to limitations of Python’s type system, this
usually only applies to low-rank array-likes.
A = np.array([[1.1, 1.2], [2.1, 2.2]])
b = np.array([1.0, 2.0])
reveal_type(np.linalg.solve(A, b))
# before: ndarray[tuple[Any, ...], dtype[float64]]
# after: ndarray[tuple[int], dtype[float64]]
stacked = np.array([[[1.0, 0.0], [0.0, 1.0]]])
reveal_type(np.linalg.inv(stacked))
# before: ndarray[tuple[Any, ...], dtype[Any]]
# after: ndarray[tuple[int, int, int], dtype[float64]]
(gh-32424)
numpy.ndarray shape-typing#
The methods and operators of numpy.ndarray now use the shape-type of the array to
infer the shape-type of the result. This includes indexing, iteration, reductions along
an axis, and the arithmetic, bitwise, and comparison operators.
Due to limitations of Python’s type system, binary operators usually only do so for
scalar operands and for arrays with the same shape-type.
x = np.ones((2, 3))
reveal_type(x[0])
# before: Any
# after: ndarray[tuple[int], dtype[float64]]
reveal_type(x.sum(axis=0))
# before: ndarray[tuple[Any, ...], dtype[float64]]
# after: ndarray[tuple[int], dtype[float64]]
reveal_type(x + x)
# before: ndarray[tuple[Any, ...], dtype[float64]]
# after: ndarray[tuple[int, int], dtype[float64]]
(gh-32540)
numpy.lib.stride_tricks shape-typing#
The numpy.lib.stride_tricks functions now use the shape and window_shape
argument types to infer the shape-type of the returned array.
x = np.arange(6.0)
reveal_type(np.lib.stride_tricks.as_strided(x, shape=(2, 3)))
# before: ndarray[tuple[Any, ...], dtype[float64]]
# after: ndarray[tuple[int, int], dtype[float64]]
reveal_type(np.lib.stride_tricks.sliding_window_view(x, 3))
# before: ndarray[tuple[Any, ...], dtype[float64]]
# after: ndarray[tuple[int, int], dtype[float64]]
(gh-32736)
numpy.emath shape-typing and dtype inference#
The numpy.emath functions now infer the shape-type of the returned array from
their inputs. For nested sequences this is limited to 1-d and 2-d inputs, and for
ndarray all shape-types are preserved.
reveal_type(np.emath.sqrt([-1, 4]))
# before: ndarray[tuple[Any, ...], dtype[Any]]
# after: ndarray[tuple[int], dtype[complex128 | float64]]
z = np.array([[1.0, -1.0]], dtype=np.complex64)
reveal_type(np.emath.log(z))
# before: ndarray[tuple[Any, ...], dtype[complexfloating]]
# after: ndarray[tuple[int, int], dtype[complex64]]
Scalar return types are also more precise. For floating-point inputs, the return type is a union of the corresponding real and complex scalar types, since the result depends on the input values.
reveal_type(np.emath.sqrt(-1.0))
# before: Any
# after: complex128 | float64
(gh-32762)
Changes#
With a NaN-like
na_objectsuch asnp.nan, casting toStringDTypeand item assignment now store the missing value for a NaN of any real or complex floating point type. Missing entries now cast to floating point and complex dtypes as NaN instead of raising an error, so NaN values round-trip.(gh-31825)
The minimum supported GCC version has been updated from 9.3.0 to 10.3.0
(gh-31843)
Structured dtypes and subarray dtypes containing
StringDTypenow consistently raiseTypeError. Formerly some structured dtpes containingStringDTypecould be created, but this could lead to data corruption or crashes on array data accesses.(gh-32027)
ndarray.byteswapnow supports dtypes that have no defined byte order (e.g. whendtype.byteorder == "|"). Such values are left unchanged, including when they occur in structured dtypes.(gh-32150)
Casting a fixed-width byte string array (
np.bytes_) toStringDTypenow raisesUnicodeDecodeErrorwhen the bytes are not valid UTF-8. Previously the invalid bytes were stored as-is and later caused undefined behavior in string operations.(gh-32296)
Some reductions that use out= with a less precise dtype than the inputs/dtype= may now return different, more precise, results.
(gh-32595)
np.spacing with NaN input no longer emits a RuntimeWarning.
(gh-32602)
pinvwithrtol=Nonedid not select the correct output dtype for integer input. It now always returns float results for integer input and no longer spuriously raises ValueError for some inputs.(gh-32679)
Doing
v[...,]on a void scalar previously returned anp.voidscalar whilev[...]returned a 0d array. Both now return a 0d array, matching the behaviour of every other scalar type.(gh-32744)
numpy.unwrap behavior changes for edge cases#
An explicitly typed discont argument passed to numpy.unwrap wider than the
result dtype is now compared at the result dtype rather than promoting. This may
change the result of numpy.unwrap by ~1 ULP.
Calling numpy.unwrap with an unsigned integer period that cannot represent
the values needed internally now raises a TypeError (“no loop found” ufunc
error, reporting the mismatched dtypes) instead of the OverflowError
raised by the previous Python implementation.
(gh-9959)
f2py line wrapping no longer produces invalid continuation lines#
Lines exceeding the column limit in f2py-generated Fortran wrappers are now
split correctly for both fixed-form and free-form source.
(gh-30967)
f2py allocatable character arrays now work correctly#
Allocatable character arrays in f2py-wrapped Fortran 90 modules no longer
raise ValueError when accessed after allocation.
(gh-30971)
NumPy’s internal memory allocations now use PyMem_RawMalloc#
NumPy’s internal memory allocations now use PyMem_RawMalloc instead of
malloc and can be tracked by tracemalloc.
(gh-31503)
Python str ufunc operands convert with the resolved dtype#
A Python str scalar containing trailing nulls now preserves the trailing nulls
in operations with StringDType. For example, np.array(["x\0"],
dtype=np.dtypes.StringDType()) == "x\0" now gives [True] rather than
[False].
(gh-32040)
ufunc.outer now follows NEP 50 promotion#
Python scalars passed to ufunc.outer were converted to arrays and thus
treated as strongly typed, unlike for a normal ufunc call. They are now weak,
so that e.g. np.add.outer(1., np.zeros(3, dtype="float32")) returns a
float32 rather than a float64 array. As a consequence, huge Python
integers now raise an OverflowError here as they do for ufunc.__call__.
(gh-32090)
ufunc.at now follows NEP 50 promotion#
Python scalars passed as the value operand of ufunc.at were converted to
arrays and thus treated as strongly typed, unlike for a normal ufunc call.
They are now weak, so the operation is computed in the promoted dtype of the
target array: e.g. np.add.at(arr, idx, 1) with a uint64 array now uses
the uint64 loop rather than float64, which rounded large values. As a
consequence, out-of-bounds Python integers now raise an OverflowError
here, as they do for ufunc.__call__; previously they wrapped silently
(e.g. adding -1 to a uint8 array produced 255).
(gh-32094)
Legacy valgrind-based C coverage tool removed#
The legacy C code-coverage tooling under tools/c_coverage/ (which relied
on valgrind’s callgrind tool) has been removed. C coverage is now collected
through gcov; build with spin build --clean --gcov and run the tests
with spin test --gcov to generate a coverage report.
(gh-32314)
MaskedArray resets a fill_value that cannot be represented in a new dtype#
A fill_value copied from a source array is now reset to the default fill_value
for the new dtype when it cannot be represented in that dtype. Previously the
copied value could be stale: ufuncs that change dtype left the result holding a
fill_value typed for the old dtype, which raised a TypeError only when
something later validated it (such as .view()), and a floating point
fill_value that overflows an integer dtype was kept as an out-of-range value
together with a RuntimeWarning. Both now fall back to the default,
including when a masked array is passed to MaskedArray with a different
dtype. A fill_value given explicitly by the user is still validated and
raises as before. This can now raise a ComplexWarning if the fill_value is
complex and the new dtype is real.