==========================
This NumPy release is the largest so made to date, some 654 PRs
contributed by 182 people have been merged. See the list of highlights
below for more details. The Python versions supported for this release
are 3.7-3.9, support for Python 3.6 has been dropped. Highlights are
- Annotations for NumPy functions. This work is ongoing and
improvements can be expected pending feedback from users.
- Wider use of SIMD to increase execution speed of ufuncs. Much work
has been done in introducing universal functions that will ease use
of modern features across different hardware platforms. This work is
ongoing.
- Preliminary work in changing the dtype and casting implementations
in order to provide an easier path to extending dtypes. This work is
ongoing but enough has been done to allow experimentation and
feedback.
- Extensive documentation improvements comprising some 185 PR merges.
This work is ongoing and part of the larger project to improve
NumPy\'s online presence and usefulness to new users.
- Further cleanups related to removing Python 2.7. This improves code
readability and removes technical debt.
- Preliminary support for the upcoming Cython 3.0.
New functions
-------------
The random.Generator class has a new `permuted` function.
The new function differs from `shuffle` and `permutation` in that the
subarrays indexed by an axis are permuted rather than the axis being
treated as a separate 1-D array for every combination of the other
indexes. For example, it is now possible to permute the rows or columns
of a 2-D array.
([gh-15121](https://github.com/numpy/numpy/pull/15121))
`sliding_window_view` provides a sliding window view for numpy arrays
[numpy.lib.stride\_tricks.sliding\_window\_view]{.title-ref} constructs
views on numpy arrays that offer a sliding or moving window access to
the array. This allows for the simple implementation of certain
algorithms, such as running means.
([gh-17394](https://github.com/numpy/numpy/pull/17394))
[numpy.broadcast\_shapes]{.title-ref} is a new user-facing function
[\~numpy.broadcast\_shapes]{.title-ref} gets the resulting shape from
broadcasting the given shape tuples against each other.
{.python}
>>> np.broadcast_shapes((1, 2), (3, 1))
(3, 2)
>>> np.broadcast_shapes(2, (3, 1))
(3, 2)
>>> np.broadcast_shapes((6, 7), (5, 6, 1), (7,), (5, 1, 7))
(5, 6, 7)
([gh-17535](https://github.com/numpy/numpy/pull/17535))
Deprecations
------------
Using the aliases of builtin types like `np.int` is deprecated
For a long time, `np.int` has been an alias of the builtin `int`. This
is repeatedly a cause of confusion for newcomers, and is also simply not
useful.
These aliases have been deprecated. The table below shows the full list
of deprecated aliases, along with their exact meaning. Replacing uses of
items in the first column with the contents of the second column will
work identically and silence the deprecation warning.
In many cases, it may have been intended to use the types from the third
column. Be aware that use of these types may result in subtle but
desirable behavior changes.
Deprecated name Identical to Possibly intended numpy type
----------------- ------------------------------- -------------------------------------------------------------------------------------------
`numpy.bool` `bool` [numpy.bool\_]{.title-ref}
`numpy.int` `int` [numpy.int\_]{.title-ref} (default int dtype), [numpy.cint]{.title-ref} (C `int`)
`numpy.float` `float` [numpy.float\_]{.title-ref}, [numpy.double]{.title-ref} (equivalent)
`numpy.complex` `complex` [numpy.complex\_]{.title-ref}, [numpy.cdouble]{.title-ref} (equivalent)
`numpy.object` `object` [numpy.object\_]{.title-ref}
`numpy.str` `str` [numpy.str\_]{.title-ref}
`numpy.long` `int` (`long` on Python 2) [numpy.int\_]{.title-ref} (C `long`), [numpy.longlong]{.title-ref} (largest integer type)
`numpy.unicode` `str` (`unicode` on Python 2) [numpy.unicode\_]{.title-ref}
Note that for technical reasons these deprecation warnings will only be
emitted on Python 3.7 and above.
([gh-14882](https://github.com/numpy/numpy/pull/14882))
Passing `shape=None` to functions with a non-optional shape argument is deprecated
Previously, this was an alias for passing `shape=()`. This deprecation
is emitted by [PyArray\_IntpConverter]{.title-ref} in the C API. If your
API is intended to support passing `None`, then you should check for
`None` prior to invoking the converter, so as to be able to distinguish
`None` and `()`.
([gh-15886](https://github.com/numpy/numpy/pull/15886))
Indexing errors will be reported even when index result is empty
In the future, NumPy will raise an IndexError when an integer array
index contains out of bound values even if a non-indexed dimension is of
length 0. This will now emit a DeprecationWarning. This can happen when
the array is previously empty, or an empty slice is involved:
arr1 = np.zeros((5, 0))
arr1[[20]]
arr2 = np.zeros((5, 5))
arr2[[20], :0]
Previously the non-empty index `[20]` was not checked for correctness.
It will now be checked causing a deprecation warning which will be
turned into an error. This also applies to assignments.
([gh-15900](https://github.com/numpy/numpy/pull/15900))
Inexact matches for `mode` and `searchside` are deprecated
Inexact and case insensitive matches for `mode` and `searchside` were
valid inputs earlier and will give a DeprecationWarning now. For
example, below are some example usages which are now deprecated and will
give a DeprecationWarning:
import numpy as np
arr = np.array([[3, 6, 6], [4, 5, 1]])
mode: inexact match
np.ravel_multi_index(arr, (7, 6), mode="clap") should be "clip"
searchside: inexact match
np.searchsorted(arr[0], 4, side='random') should be "right"
([gh-16056](https://github.com/numpy/numpy/pull/16056))
Deprecation of [numpy.dual]{.title-ref}
The module [numpy.dual]{.title-ref} is deprecated. Instead of importing
functions from [numpy.dual]{.title-ref}, the functions should be
imported directly from NumPy or SciPy.
([gh-16156](https://github.com/numpy/numpy/pull/16156))
`outer` and `ufunc.outer` deprecated for matrix
`np.matrix` use with [\~numpy.outer]{.title-ref} or generic ufunc outer
calls such as `numpy.add.outer`. Previously, matrix was converted to an
array here. This will not be done in the future requiring a manual
conversion to arrays.
([gh-16232](https://github.com/numpy/numpy/pull/16232))
Further Numeric Style types Deprecated
The remaining numeric-style type codes `Bytes0`, `Str0`, `Uint32`,
`Uint64`, and `Datetime64` have been deprecated. The lower-case variants
should be used instead. For bytes and string `"S"` and `"U"` are further
alternatives.
([gh-16554](https://github.com/numpy/numpy/pull/16554))
The `ndincr` method of `ndindex` is deprecated
The documentation has warned against using this function since NumPy
1.8. Use `next(it)` instead of `it.ndincr()`.
([gh-17233](https://github.com/numpy/numpy/pull/17233))
Future Changes
--------------
Arrays cannot be using subarray dtypes
Array creation and casting using `np.array(arr, dtype)` and
`arr.astype(dtype)` will use different logic when `dtype` is a subarray
dtype such as `np.dtype("(2)i,")`.
For such a `dtype` the following behaviour is true:
res = np.array(arr, dtype)
res.dtype is not dtype
res.dtype is dtype.base
res.shape == arr.shape + dtype.shape
But `res` is filled using the logic:
res = np.empty(arr.shape + dtype.shape, dtype=dtype.base)
res[...] = arr
which uses incorrect broadcasting (and often leads to an error). In the
future, this will instead cast each element individually, leading to the
same result as:
res = np.array(arr, dtype=np.dtype(["f", dtype]))["f"]
Which can normally be used to opt-in to the new behaviour.
This change does not affect `np.array(list, dtype="(2)i,")` unless the
`list` itself includes at least one array. In particular, the behaviour
is unchanged for a list of tuples.
([gh-17596](https://github.com/numpy/numpy/pull/17596))
Expired deprecations
--------------------
- The deprecation of numeric style type-codes `np.dtype("Complex64")`
(with upper case spelling), is expired. `"Complex64"` corresponded
to `"complex128"` and `"Complex32"` corresponded to `"complex64"`.
- The deprecation of `np.sctypeNA` and `np.typeNA` is expired. Both
have been removed from the public API. Use `np.typeDict` instead.
([gh-16554](https://github.com/numpy/numpy/pull/16554))
- The 14-year deprecation of `np.ctypeslib.ctypes_load_library` is
expired. Use `~numpy.ctypeslib.load_library`{.interpreted-text
role="func"} instead, which is identical.
([gh-17116](https://github.com/numpy/numpy/pull/17116))
Financial functions removed
In accordance with NEP 32, the financial functions are removed from
NumPy 1.20. The functions that have been removed are `fv`, `ipmt`,
`irr`, `mirr`, `nper`, `npv`, `pmt`, `ppmt`, `pv`, and `rate`. These
functions are available in the
[numpy\_financial](https://pypi.org/project/numpy-financial) library.
([gh-17067](https://github.com/numpy/numpy/pull/17067))
Compatibility notes
-------------------
Same kind casting in concatenate with `axis=None`
When [\~numpy.concatenate]{.title-ref} is called with `axis=None`, the
flattened arrays were cast with `unsafe`. Any other axis choice uses
\"same kind\". That different default has been deprecated and \"same
kind\" casting will be used instead. The new `casting` keyword argument
can be used to retain the old behaviour.
([gh-16134](https://github.com/numpy/numpy/pull/16134))
NumPy Scalars are cast when assigned to arrays
When creating or assigning to arrays, in all relevant cases NumPy
scalars will now be cast identically to NumPy arrays. In particular this
changes the behaviour in some cases which previously raised an error:
np.array([np.float64(np.nan)], dtype=np.int64)
will succeed and return an undefined result (usually the smallest
possible integer). This also affects assignments:
arr[0] = np.float64(np.nan)
At this time, NumPy retains the behaviour for:
np.array(np.float64(np.nan), dtype=np.int64)
The above changes do not affect Python scalars:
np.array([float("NaN")], dtype=np.int64)
remains unaffected (`np.nan` is a Python `float`, not a NumPy one).
Unlike signed integers, unsigned integers do not retain this special
case, since they always behaved more like casting. The following code
stops raising an error:
np.array([np.float64(np.nan)], dtype=np.uint64)
To avoid backward compatibility issues, at this time assignment from
`datetime64` scalar to strings of too short length remains supported.
This means that `np.asarray(np.datetime64("2020-10-10"), dtype="S5")`
succeeds now, when it failed before. In the long term this may be
deprecated or the unsafe cast may be allowed generally to make
assignment of arrays and scalars behave consistently.
Array coercion changes when Strings and other types are mixed
When strings and other types are mixed, such as:
np.array(["string", np.float64(3.)], dtype="S")
The results will change, which may lead to string dtypes with longer
strings in some cases. In particularly, if `dtype="S"` is not provided
any numerical value will lead to a string results long enough to hold
all possible numerical values. (e.g. \"S32\" for floats). Note that you
should always provide `dtype="S"` when converting non-strings to
strings.
If `dtype="S"` is provided the results will be largely identical to
before, but NumPy scalars (not a Python float like `1.0`), will still
enforce a uniform string length:
np.array([np.float64(3.)], dtype="S") gives "S32"
np.array([3.0], dtype="S") gives "S3"
Previously the first version gave the same result as the second.
Array coercion restructure
Array coercion has been restructured. In general, this should not affect
users. In extremely rare corner cases where array-likes are nested:
np.array([array_like1])
Things will now be more consistent with:
np.array([np.array(array_like1)])
This could potentially subtly change output for badly defined
array-likes. We are not aware of any such case where the results were
not clearly incorrect previously.
([gh-16200](https://github.com/numpy/numpy/pull/16200))
Writing to the result of [numpy.broadcast\_arrays]{.title-ref} will export readonly buffers
In NumPy 1.17 [numpy.broadcast\_arrays]{.title-ref} started warning when
the resulting array was written to. This warning was skipped when the
array was used through the buffer interface (e.g. `memoryview(arr)`).
The same thing will now occur for the two protocols
`__array_interface__`, and `__array_struct__` returning read-only
buffers instead of giving a warning.
([gh-16350](https://github.com/numpy/numpy/pull/16350))
Numeric-style type names have been removed from type dictionaries
To stay in sync with the deprecation for `np.dtype("Complex64")` and
other numeric-style (capital case) types. These were removed from
`np.sctypeDict` and `np.typeDict`. You should use the lower case
versions instead. Note that `"Complex64"` corresponds to `"complex128"`
and `"Complex32"` corresponds to `"complex64"`. The numpy style (new)
versions, denote the full size and not the size of the real/imaginary
part.
([gh-16554](https://github.com/numpy/numpy/pull/16554))
The `operator.concat` function now raises TypeError for array arguments
The previous behavior was to fall back to addition and add the two
arrays, which was thought to be unexpected behavior for a concatenation
function.
([gh-16570](https://github.com/numpy/numpy/pull/16570))
`nickname` attribute removed from ABCPolyBase
An abstract property `nickname` has been removed from `ABCPolyBase` as
it was no longer used in the derived convenience classes. This may
affect users who have derived classes from `ABCPolyBase` and overridden
the methods for representation and display, e.g. `__str__`, `__repr__`,
`_repr_latex`, etc.
([gh-16589](https://github.com/numpy/numpy/pull/16589))
`float->timedelta` and `uint64->timedelta` promotion will raise a TypeError
Float and timedelta promotion consistently raises a TypeError.
`np.promote_types("float32", "m8")` aligns with
`np.promote_types("m8", "float32")` now and both raise a TypeError.
Previously, `np.promote_types("float32", "m8")` returned `"m8"` which
was considered a bug.
Uint64 and timedelta promotion consistently raises a TypeError.
`np.promote_types("uint64", "m8")` aligns with
`np.promote_types("m8", "uint64")` now and both raise a TypeError.
Previously, `np.promote_types("uint64", "m8")` returned `"m8"` which was
considered a bug.
([gh-16592](https://github.com/numpy/numpy/pull/16592))
`numpy.genfromtxt` now correctly unpacks structured arrays
Previously, [numpy.genfromtxt]{.title-ref} failed to unpack if it was
called with `unpack=True` and a structured datatype was passed to the
`dtype` argument (or `dtype=None` was passed and a structured datatype
was inferred). For example:
>>> data = StringIO("21 58.0\n35 72.0")
>>> np.genfromtxt(data, dtype=None, unpack=True)
array([(21, 58.), (35, 72.)], dtype=[('f0', '<i8'), ('f1', '<f8')])
Structured arrays will now correctly unpack into a list of arrays, one
for each column:
>>> np.genfromtxt(data, dtype=None, unpack=True)
[array([21, 35]), array([58., 72.])]
([gh-16650](https://github.com/numpy/numpy/pull/16650))
`mgrid`, `r_`, etc. consistently return correct outputs for non-default precision input
Previously,
`np.mgrid[np.float32(0.1):np.float32(0.35):np.float32(0.1),]` and
`np.r_[0:10:np.complex64(3j)]` failed to return meaningful output. This
bug potentially affects [\~numpy.mgrid]{.title-ref},
[\~numpy.ogrid]{.title-ref}, [\~numpy.r\_]{.title-ref}, and
[\~numpy.c\_]{.title-ref} when an input with dtype other than the
default `float64` and `complex128` and equivalent Python types were
used. The methods have been fixed to handle varying precision correctly.
([gh-16815](https://github.com/numpy/numpy/pull/16815))
Boolean array indices with mismatching shapes now properly give `IndexError`
Previously, if a boolean array index matched the size of the indexed
array but not the shape, it was incorrectly allowed in some cases. In
other cases, it gave an error, but the error was incorrectly a
`ValueError` with a message about broadcasting instead of the correct
`IndexError`.
For example, the following used to incorrectly give
`ValueError: operands could not be broadcast together with shapes (2,2) (1,4)`:
{.python}
np.empty((2, 2))[np.array([[True, False, False, False]])]
And the following used to incorrectly return `array([], dtype=float64)`:
{.python}
np.empty((2, 2))[np.array([[False, False, False, False]])]
Both now correctly give
`IndexError: boolean index did not match indexed array along dimension 0; dimension is 2 but corresponding boolean dimension is 1`.
([gh-17010](https://github.com/numpy/numpy/pull/17010))
Casting errors interrupt Iteration
When iterating while casting values, an error may stop the iteration
earlier than before. In any case, a failed casting operation always
returned undefined, partial results. Those may now be even more
undefined and partial. For users of the `NpyIter` C-API such cast errors
will now cause the [iternext()]{.title-ref} function to return 0 and
thus abort iteration. Currently, there is no API to detect such an error
directly. It is necessary to check `PyErr_Occurred()`, which may be
problematic in combination with `NpyIter_Reset`. These issues always
existed, but new API could be added if required by users.
([gh-17029](https://github.com/numpy/numpy/pull/17029))
f2py generated code may return unicode instead of byte strings
Some byte strings previously returned by f2py generated code may now be
unicode strings. This results from the ongoing Python2 -\> Python3
cleanup.
([gh-17068](https://github.com/numpy/numpy/pull/17068))
The first element of the `__array_interface__["data"]` tuple must be an integer
This has been the documented interface for many years, but there was
still code that would accept a byte string representation of the pointer
address. That code has been removed, passing the address as a byte
string will now raise an error.
([gh-17241](https://github.com/numpy/numpy/pull/17241))
poly1d respects the dtype of all-zero argument
Previously, constructing an instance of `poly1d` with all-zero
coefficients would cast the coefficients to `np.float64`. This affected
the output dtype of methods which construct `poly1d` instances
internally, such as `np.polymul`.
([gh-17577](https://github.com/numpy/numpy/pull/17577))
The numpy.i file for swig is Python 3 only.
Uses of Python 2.7 C-API functions have been updated to Python 3 only.
Users who need the old version should take it from an older version of
NumPy.
([gh-17580](https://github.com/numpy/numpy/pull/17580))
Void dtype discovery in `np.array`
In calls using `np.array(..., dtype="V")`, `arr.astype("V")`, and
similar a TypeError will now be correctly raised unless all elements
have the identical void length. An example for this is:
np.array([b"1", b"12"], dtype="V")
Which previously returned an array with dtype `"V2"` which cannot
represent `b"1"` faithfully.
([gh-17706](https://github.com/numpy/numpy/pull/17706))
C API changes
-------------
Size of `np.ndarray` and `np.void_` changed
The size of the `PyArrayObject` and `PyVoidScalarObject` structures have
changed. The following header definition has been removed:
define NPY_SIZEOF_PYARRAYOBJECT (sizeof(PyArrayObject_fields))
since the size must not be considered a compile time constant: it will
change for different runtime versions of NumPy.
The most likely relevant use are potential subclasses written in C which
will have to be recompiled and should be updated. Please see the
documentation for :c`PyArrayObject`{.interpreted-text role="type"} for
more details and contact the NumPy developers if you are affected by
this change.
NumPy will attempt to give a graceful error but a program expecting a
fixed structure size may have undefined behaviour and likely crash.
([gh-16938](https://github.com/numpy/numpy/pull/16938))
New Features
------------
`where` keyword argument for `numpy.all` and `numpy.any` functions
The keyword argument `where` is added and allows to only consider
specified elements or subaxes from an array in the Boolean evaluation of
`all` and `any`. This new keyword is available to the functions `all`
and `any` both via `numpy` directly or in the methods of
`numpy.ndarray`.
Any broadcastable Boolean array or a scalar can be set as `where`. It
defaults to `True` to evaluate the functions for all elements in an
array if `where` is not set by the user. Examples are given in the
documentation of the functions.
`where` keyword argument for `numpy` functions `mean`, `std`, `var`
The keyword argument `where` is added and allows to limit the scope in
the calculation of `mean`, `std` and `var` to only a subset of elements.
It is available both via `numpy` directly or in the methods of
`numpy.ndarray`.
Any broadcastable Boolean array or a scalar can be set as `where`. It
defaults to `True` to evaluate the functions for all elements in an
array if `where` is not set by the user. Examples are given in the
documentation of the functions.
([gh-15852](https://github.com/numpy/numpy/pull/15852))
`norm=backward`, `forward` keyword options for `numpy.fft` functions
The keyword argument option `norm=backward` is added as an alias for
`None` and acts as the default option; using it has the direct
transforms unscaled and the inverse transforms scaled by `1/n`.
Using the new keyword argument option `norm=forward` has the direct
transforms scaled by `1/n` and the inverse transforms unscaled (i.e.
exactly opposite to the default option `norm=backward`).
([gh-16476](https://github.com/numpy/numpy/pull/16476))
NumPy is now typed
Type annotations have been added for large parts of NumPy. There is also
a new [numpy.typing]{.title-ref} module that contains useful types for
end-users. The currently available types are
- `ArrayLike`: for objects that can be coerced to an array
- `DtypeLike`: for objects that can be coerced to a dtype
([gh-16515](https://github.com/numpy/numpy/pull/16515))
`numpy.typing` is accessible at runtime
The types in `numpy.typing` can now be imported at runtime. Code like
the following will now work:
{.python}
from numpy.typing import ArrayLike
x: ArrayLike = [1, 2, 3, 4]
([gh-16558](https://github.com/numpy/numpy/pull/16558))
New `__f2py_numpy_version__` attribute for f2py generated modules.
Because f2py is released together with NumPy, `__f2py_numpy_version__`
provides a way to track the version f2py used to generate the module.
([gh-16594](https://github.com/numpy/numpy/pull/16594))
`mypy` tests can be run via runtests.py
Currently running mypy with the NumPy stubs configured requires either:
- Installing NumPy
- Adding the source directory to MYPYPATH and linking to the
`mypy.ini`
Both options are somewhat inconvenient, so add a `--mypy` option to
runtests that handles setting things up for you. This will also be
useful in the future for any typing codegen since it will ensure the
project is built before type checking.
([gh-17123](https://github.com/numpy/numpy/pull/17123))
Negation of user defined BLAS/LAPACK detection order
[\~numpy.distutils]{.title-ref} allows negation of libraries when
determining BLAS/LAPACK libraries. This may be used to remove an item
from the library resolution phase, i.e. to disallow NetLIB libraries one
could do:
{.bash}
NPY_BLAS_ORDER='^blas' NPY_LAPACK_ORDER='^lapack' python setup.py build
That will use any of the accelerated libraries instead.
([gh-17219](https://github.com/numpy/numpy/pull/17219))
Allow passing optimizations arguments to asv build
It is now possible to pass `-j`, `--cpu-baseline`, `--cpu-dispatch` and
`--disable-optimization` flags to ASV build when the `--bench-compare`
argument is used.
([gh-17284](https://github.com/numpy/numpy/pull/17284))
The NVIDIA HPC SDK nvfortran compiler is now supported
Support for the nvfortran compiler, a version of pgfortran, has been
added.
([gh-17344](https://github.com/numpy/numpy/pull/17344))
`dtype` option for `cov` and `corrcoef`
The `dtype` option is now available for [numpy.cov]{.title-ref} and
[numpy.corrcoef]{.title-ref}. It specifies which data-type the returned
result should have. By default the functions still return a
[numpy.float64]{.title-ref} result.
([gh-17456](https://github.com/numpy/numpy/pull/17456))
Improvements
------------
Improved string representation for polynomials (`__str__`)
The string representation (`__str__`) of all six polynomial types in
[numpy.polynomial]{.title-ref} has been updated to give the polynomial
as a mathematical expression instead of an array of coefficients. Two
package-wide formats for the polynomial expressions are available - one
using Unicode characters for superscripts and subscripts, and another
using only ASCII characters.
([gh-15666](https://github.com/numpy/numpy/pull/15666))
Remove the Accelerate library as a candidate LAPACK library
Apple no longer supports Accelerate. Remove it.
([gh-15759](https://github.com/numpy/numpy/pull/15759))
Object arrays containing multi-line objects have a more readable `repr`
If elements of an object array have a `repr` containing new lines, then
the wrapped lines will be aligned by column. Notably, this improves the
`repr` of nested arrays:
>>> np.array([np.eye(2), np.eye(3)], dtype=object)
array([array([[1., 0.],
[0., 1.]]),
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])], dtype=object)
([gh-15997](https://github.com/numpy/numpy/pull/15997))
Concatenate supports providing an output dtype
Support was added to [\~numpy.concatenate]{.title-ref} to provide an
output `dtype` and `casting` using keyword arguments. The `dtype`
argument cannot be provided in conjunction with the `out` one.
([gh-16134](https://github.com/numpy/numpy/pull/16134))
Thread safe f2py callback functions
Callback functions in f2py are now thread safe.
([gh-16519](https://github.com/numpy/numpy/pull/16519))
[numpy.core.records.fromfile]{.title-ref} now supports file-like objects
[numpy.rec.fromfile]{.title-ref} can now use file-like objects, for
instance :py`io.BytesIO`{.interpreted-text role="class"}
([gh-16675](https://github.com/numpy/numpy/pull/16675))
RPATH support on AIX added to distutils
This allows SciPy to be built on AIX.
([gh-16710](https://github.com/numpy/numpy/pull/16710))
Use f90 compiler specified by the command line args
The compiler command selection for Fortran Portland Group Compiler is
changed in [numpy.distutils.fcompiler]{.title-ref}. This only affects
the linking command. This forces the use of the executable provided by
the command line option (if provided) instead of the pgfortran
executable. If no executable is provided to the command line option it
defaults to the pgf90 executable, wich is an alias for pgfortran
according to the PGI documentation.
([gh-16730](https://github.com/numpy/numpy/pull/16730))
Add NumPy declarations for Cython 3.0 and later
The pxd declarations for Cython 3.0 were improved to avoid using
deprecated NumPy C-API features. Extension modules built with Cython