summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatti Picus <matti.picus@gmail.com>2021-03-21 07:48:10 +0200
committerGitHub <noreply@github.com>2021-03-21 07:48:10 +0200
commit9e47444aa66ae055c3ef5a01d579d2eb52606f20 (patch)
treef96ff12e2a8072d3ea47624922914f44aa463f00
parent9629cd9221766b087478d3dceca8c260b76e82b7 (diff)
parent40b8ba3f43e28cb543bbb1d5aff095da264bafd8 (diff)
downloadnumpy-9e47444aa66ae055c3ef5a01d579d2eb52606f20.tar.gz
Merge pull request #18642 from seberg/splitup-faster-argparsing-optimize-asarray
ENH: Use new argument parsing for array creation functions
-rw-r--r--numpy/core/_add_newdocs.py236
-rw-r--r--numpy/core/_asarray.py275
-rw-r--r--numpy/core/_asarray.pyi4
-rw-r--r--numpy/core/_methods.py2
-rw-r--r--numpy/core/fromnumeric.py3
-rw-r--r--numpy/core/multiarray.py7
-rw-r--r--numpy/core/numeric.py9
-rw-r--r--numpy/core/shape_base.py3
-rw-r--r--numpy/core/src/multiarray/arrayfunction_override.c105
-rw-r--r--numpy/core/src/multiarray/arrayfunction_override.h4
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c516
-rw-r--r--numpy/core/tests/test_multiarray.py27
-rw-r--r--numpy/core/tests/test_overrides.py3
-rw-r--r--numpy/ctypeslib.py4
-rw-r--r--numpy/lib/function_base.py9
-rw-r--r--numpy/lib/shape_base.py2
-rw-r--r--numpy/ma/core.py2
-rw-r--r--numpy/ma/testutils.py4
-rw-r--r--numpy/testing/_private/utils.py24
19 files changed, 694 insertions, 545 deletions
diff --git a/numpy/core/_add_newdocs.py b/numpy/core/_add_newdocs.py
index fb2930143..bba9f95fc 100644
--- a/numpy/core/_add_newdocs.py
+++ b/numpy/core/_add_newdocs.py
@@ -904,6 +904,242 @@ add_newdoc('numpy.core.multiarray', 'array',
array_function_like_doc,
))
+add_newdoc('numpy.core.multiarray', 'asarray',
+ """
+ asarray(a, dtype=None, order=None, *, like=None)
+
+ Convert the input to an array.
+
+ Parameters
+ ----------
+ a : array_like
+ Input data, in any form that can be converted to an array. This
+ includes lists, lists of tuples, tuples, tuples of tuples, tuples
+ of lists and ndarrays.
+ dtype : data-type, optional
+ By default, the data-type is inferred from the input data.
+ order : {'C', 'F', 'A', 'K'}, optional
+ Memory layout. 'A' and 'K' depend on the order of input array a.
+ 'C' row-major (C-style),
+ 'F' column-major (Fortran-style) memory representation.
+ 'A' (any) means 'F' if `a` is Fortran contiguous, 'C' otherwise
+ 'K' (keep) preserve input order
+ Defaults to 'C'.
+ ${ARRAY_FUNCTION_LIKE}
+
+ .. versionadded:: 1.20.0
+
+ Returns
+ -------
+ out : ndarray
+ Array interpretation of `a`. No copy is performed if the input
+ is already an ndarray with matching dtype and order. If `a` is a
+ subclass of ndarray, a base class ndarray is returned.
+
+ See Also
+ --------
+ asanyarray : Similar function which passes through subclasses.
+ ascontiguousarray : Convert input to a contiguous array.
+ asfarray : Convert input to a floating point ndarray.
+ asfortranarray : Convert input to an ndarray with column-major
+ memory order.
+ asarray_chkfinite : Similar function which checks input for NaNs and Infs.
+ fromiter : Create an array from an iterator.
+ fromfunction : Construct an array by executing a function on grid
+ positions.
+
+ Examples
+ --------
+ Convert a list into an array:
+
+ >>> a = [1, 2]
+ >>> np.asarray(a)
+ array([1, 2])
+
+ Existing arrays are not copied:
+
+ >>> a = np.array([1, 2])
+ >>> np.asarray(a) is a
+ True
+
+ If `dtype` is set, array is copied only if dtype does not match:
+
+ >>> a = np.array([1, 2], dtype=np.float32)
+ >>> np.asarray(a, dtype=np.float32) is a
+ True
+ >>> np.asarray(a, dtype=np.float64) is a
+ False
+
+ Contrary to `asanyarray`, ndarray subclasses are not passed through:
+
+ >>> issubclass(np.recarray, np.ndarray)
+ True
+ >>> a = np.array([(1.0, 2), (3.0, 4)], dtype='f4,i4').view(np.recarray)
+ >>> np.asarray(a) is a
+ False
+ >>> np.asanyarray(a) is a
+ True
+
+ """.replace(
+ "${ARRAY_FUNCTION_LIKE}",
+ array_function_like_doc,
+ ))
+
+add_newdoc('numpy.core.multiarray', 'asanyarray',
+ """
+ asanyarray(a, dtype=None, order=None, *, like=None)
+
+ Convert the input to an ndarray, but pass ndarray subclasses through.
+
+ Parameters
+ ----------
+ a : array_like
+ Input data, in any form that can be converted to an array. This
+ includes scalars, lists, lists of tuples, tuples, tuples of tuples,
+ tuples of lists, and ndarrays.
+ dtype : data-type, optional
+ By default, the data-type is inferred from the input data.
+ order : {'C', 'F', 'A', 'K'}, optional
+ Memory layout. 'A' and 'K' depend on the order of input array a.
+ 'C' row-major (C-style),
+ 'F' column-major (Fortran-style) memory representation.
+ 'A' (any) means 'F' if `a` is Fortran contiguous, 'C' otherwise
+ 'K' (keep) preserve input order
+ Defaults to 'C'.
+ ${ARRAY_FUNCTION_LIKE}
+
+ .. versionadded:: 1.20.0
+
+ Returns
+ -------
+ out : ndarray or an ndarray subclass
+ Array interpretation of `a`. If `a` is an ndarray or a subclass
+ of ndarray, it is returned as-is and no copy is performed.
+
+ See Also
+ --------
+ asarray : Similar function which always returns ndarrays.
+ ascontiguousarray : Convert input to a contiguous array.
+ asfarray : Convert input to a floating point ndarray.
+ asfortranarray : Convert input to an ndarray with column-major
+ memory order.
+ asarray_chkfinite : Similar function which checks input for NaNs and
+ Infs.
+ fromiter : Create an array from an iterator.
+ fromfunction : Construct an array by executing a function on grid
+ positions.
+
+ Examples
+ --------
+ Convert a list into an array:
+
+ >>> a = [1, 2]
+ >>> np.asanyarray(a)
+ array([1, 2])
+
+ Instances of `ndarray` subclasses are passed through as-is:
+
+ >>> a = np.array([(1.0, 2), (3.0, 4)], dtype='f4,i4').view(np.recarray)
+ >>> np.asanyarray(a) is a
+ True
+
+ """.replace(
+ "${ARRAY_FUNCTION_LIKE}",
+ array_function_like_doc,
+ ))
+
+add_newdoc('numpy.core.multiarray', 'ascontiguousarray',
+ """
+ ascontiguousarray(a, dtype=None, *, like=None)
+
+ Return a contiguous array (ndim >= 1) in memory (C order).
+
+ Parameters
+ ----------
+ a : array_like
+ Input array.
+ dtype : str or dtype object, optional
+ Data-type of returned array.
+ ${ARRAY_FUNCTION_LIKE}
+
+ .. versionadded:: 1.20.0
+
+ Returns
+ -------
+ out : ndarray
+ Contiguous array of same shape and content as `a`, with type `dtype`
+ if specified.
+
+ See Also
+ --------
+ asfortranarray : Convert input to an ndarray with column-major
+ memory order.
+ require : Return an ndarray that satisfies requirements.
+ ndarray.flags : Information about the memory layout of the array.
+
+ Examples
+ --------
+ >>> x = np.arange(6).reshape(2,3)
+ >>> np.ascontiguousarray(x, dtype=np.float32)
+ array([[0., 1., 2.],
+ [3., 4., 5.]], dtype=float32)
+ >>> x.flags['C_CONTIGUOUS']
+ True
+
+ Note: This function returns an array with at least one-dimension (1-d)
+ so it will not preserve 0-d arrays.
+
+ """.replace(
+ "${ARRAY_FUNCTION_LIKE}",
+ array_function_like_doc,
+ ))
+
+add_newdoc('numpy.core.multiarray', 'asfortranarray',
+ """
+ asfortranarray(a, dtype=None, *, like=None)
+
+ Return an array (ndim >= 1) laid out in Fortran order in memory.
+
+ Parameters
+ ----------
+ a : array_like
+ Input array.
+ dtype : str or dtype object, optional
+ By default, the data-type is inferred from the input data.
+ ${ARRAY_FUNCTION_LIKE}
+
+ .. versionadded:: 1.20.0
+
+ Returns
+ -------
+ out : ndarray
+ The input `a` in Fortran, or column-major, order.
+
+ See Also
+ --------
+ ascontiguousarray : Convert input to a contiguous (C order) array.
+ asanyarray : Convert input to an ndarray with either row or
+ column-major memory order.
+ require : Return an ndarray that satisfies requirements.
+ ndarray.flags : Information about the memory layout of the array.
+
+ Examples
+ --------
+ >>> x = np.arange(6).reshape(2,3)
+ >>> y = np.asfortranarray(x)
+ >>> x.flags['F_CONTIGUOUS']
+ False
+ >>> y.flags['F_CONTIGUOUS']
+ True
+
+ Note: This function returns an array with at least one-dimension (1-d)
+ so it will not preserve 0-d arrays.
+
+ """.replace(
+ "${ARRAY_FUNCTION_LIKE}",
+ array_function_like_doc,
+ ))
+
add_newdoc('numpy.core.multiarray', 'empty',
"""
empty(shape, dtype=float, order='C', *, like=None)
diff --git a/numpy/core/_asarray.py b/numpy/core/_asarray.py
index a406308f3..ecb4e7c39 100644
--- a/numpy/core/_asarray.py
+++ b/numpy/core/_asarray.py
@@ -8,283 +8,12 @@ from .overrides import (
set_array_function_like_doc,
set_module,
)
-from .multiarray import array
+from .multiarray import array, asanyarray
-__all__ = [
- "asarray", "asanyarray", "ascontiguousarray", "asfortranarray", "require",
-]
+__all__ = ["require"]
-def _asarray_dispatcher(a, dtype=None, order=None, *, like=None):
- return (like,)
-
-
-@set_array_function_like_doc
-@set_module('numpy')
-def asarray(a, dtype=None, order=None, *, like=None):
- """Convert the input to an array.
-
- Parameters
- ----------
- a : array_like
- Input data, in any form that can be converted to an array. This
- includes lists, lists of tuples, tuples, tuples of tuples, tuples
- of lists and ndarrays.
- dtype : data-type, optional
- By default, the data-type is inferred from the input data.
- order : {'C', 'F', 'A', 'K'}, optional
- Memory layout. 'A' and 'K' depend on the order of input array a.
- 'C' row-major (C-style),
- 'F' column-major (Fortran-style) memory representation.
- 'A' (any) means 'F' if `a` is Fortran contiguous, 'C' otherwise
- 'K' (keep) preserve input order
- Defaults to 'C'.
- ${ARRAY_FUNCTION_LIKE}
-
- .. versionadded:: 1.20.0
-
- Returns
- -------
- out : ndarray
- Array interpretation of `a`. No copy is performed if the input
- is already an ndarray with matching dtype and order. If `a` is a
- subclass of ndarray, a base class ndarray is returned.
-
- See Also
- --------
- asanyarray : Similar function which passes through subclasses.
- ascontiguousarray : Convert input to a contiguous array.
- asfarray : Convert input to a floating point ndarray.
- asfortranarray : Convert input to an ndarray with column-major
- memory order.
- asarray_chkfinite : Similar function which checks input for NaNs and Infs.
- fromiter : Create an array from an iterator.
- fromfunction : Construct an array by executing a function on grid
- positions.
-
- Examples
- --------
- Convert a list into an array:
-
- >>> a = [1, 2]
- >>> np.asarray(a)
- array([1, 2])
-
- Existing arrays are not copied:
-
- >>> a = np.array([1, 2])
- >>> np.asarray(a) is a
- True
-
- If `dtype` is set, array is copied only if dtype does not match:
-
- >>> a = np.array([1, 2], dtype=np.float32)
- >>> np.asarray(a, dtype=np.float32) is a
- True
- >>> np.asarray(a, dtype=np.float64) is a
- False
-
- Contrary to `asanyarray`, ndarray subclasses are not passed through:
-
- >>> issubclass(np.recarray, np.ndarray)
- True
- >>> a = np.array([(1.0, 2), (3.0, 4)], dtype='f4,i4').view(np.recarray)
- >>> np.asarray(a) is a
- False
- >>> np.asanyarray(a) is a
- True
-
- """
- if like is not None:
- return _asarray_with_like(a, dtype=dtype, order=order, like=like)
-
- return array(a, dtype, copy=False, order=order)
-
-
-_asarray_with_like = array_function_dispatch(
- _asarray_dispatcher
-)(asarray)
-
-
-@set_array_function_like_doc
-@set_module('numpy')
-def asanyarray(a, dtype=None, order=None, *, like=None):
- """Convert the input to an ndarray, but pass ndarray subclasses through.
-
- Parameters
- ----------
- a : array_like
- Input data, in any form that can be converted to an array. This
- includes scalars, lists, lists of tuples, tuples, tuples of tuples,
- tuples of lists, and ndarrays.
- dtype : data-type, optional
- By default, the data-type is inferred from the input data.
- order : {'C', 'F', 'A', 'K'}, optional
- Memory layout. 'A' and 'K' depend on the order of input array a.
- 'C' row-major (C-style),
- 'F' column-major (Fortran-style) memory representation.
- 'A' (any) means 'F' if `a` is Fortran contiguous, 'C' otherwise
- 'K' (keep) preserve input order
- Defaults to 'C'.
- ${ARRAY_FUNCTION_LIKE}
-
- .. versionadded:: 1.20.0
-
- Returns
- -------
- out : ndarray or an ndarray subclass
- Array interpretation of `a`. If `a` is an ndarray or a subclass
- of ndarray, it is returned as-is and no copy is performed.
-
- See Also
- --------
- asarray : Similar function which always returns ndarrays.
- ascontiguousarray : Convert input to a contiguous array.
- asfarray : Convert input to a floating point ndarray.
- asfortranarray : Convert input to an ndarray with column-major
- memory order.
- asarray_chkfinite : Similar function which checks input for NaNs and
- Infs.
- fromiter : Create an array from an iterator.
- fromfunction : Construct an array by executing a function on grid
- positions.
-
- Examples
- --------
- Convert a list into an array:
-
- >>> a = [1, 2]
- >>> np.asanyarray(a)
- array([1, 2])
-
- Instances of `ndarray` subclasses are passed through as-is:
-
- >>> a = np.array([(1.0, 2), (3.0, 4)], dtype='f4,i4').view(np.recarray)
- >>> np.asanyarray(a) is a
- True
-
- """
- if like is not None:
- return _asanyarray_with_like(a, dtype=dtype, order=order, like=like)
-
- return array(a, dtype, copy=False, order=order, subok=True)
-
-
-_asanyarray_with_like = array_function_dispatch(
- _asarray_dispatcher
-)(asanyarray)
-
-
-def _asarray_contiguous_fortran_dispatcher(a, dtype=None, *, like=None):
- return (like,)
-
-
-@set_array_function_like_doc
-@set_module('numpy')
-def ascontiguousarray(a, dtype=None, *, like=None):
- """
- Return a contiguous array (ndim >= 1) in memory (C order).
-
- Parameters
- ----------
- a : array_like
- Input array.
- dtype : str or dtype object, optional
- Data-type of returned array.
- ${ARRAY_FUNCTION_LIKE}
-
- .. versionadded:: 1.20.0
-
- Returns
- -------
- out : ndarray
- Contiguous array of same shape and content as `a`, with type `dtype`
- if specified.
-
- See Also
- --------
- asfortranarray : Convert input to an ndarray with column-major
- memory order.
- require : Return an ndarray that satisfies requirements.
- ndarray.flags : Information about the memory layout of the array.
-
- Examples
- --------
- >>> x = np.arange(6).reshape(2,3)
- >>> np.ascontiguousarray(x, dtype=np.float32)
- array([[0., 1., 2.],
- [3., 4., 5.]], dtype=float32)
- >>> x.flags['C_CONTIGUOUS']
- True
-
- Note: This function returns an array with at least one-dimension (1-d)
- so it will not preserve 0-d arrays.
-
- """
- if like is not None:
- return _ascontiguousarray_with_like(a, dtype=dtype, like=like)
-
- return array(a, dtype, copy=False, order='C', ndmin=1)
-
-
-_ascontiguousarray_with_like = array_function_dispatch(
- _asarray_contiguous_fortran_dispatcher
-)(ascontiguousarray)
-
-
-@set_array_function_like_doc
-@set_module('numpy')
-def asfortranarray(a, dtype=None, *, like=None):
- """
- Return an array (ndim >= 1) laid out in Fortran order in memory.
-
- Parameters
- ----------
- a : array_like
- Input array.
- dtype : str or dtype object, optional
- By default, the data-type is inferred from the input data.
- ${ARRAY_FUNCTION_LIKE}
-
- .. versionadded:: 1.20.0
-
- Returns
- -------
- out : ndarray
- The input `a` in Fortran, or column-major, order.
-
- See Also
- --------
- ascontiguousarray : Convert input to a contiguous (C order) array.
- asanyarray : Convert input to an ndarray with either row or
- column-major memory order.
- require : Return an ndarray that satisfies requirements.
- ndarray.flags : Information about the memory layout of the array.
-
- Examples
- --------
- >>> x = np.arange(6).reshape(2,3)
- >>> y = np.asfortranarray(x)
- >>> x.flags['F_CONTIGUOUS']
- False
- >>> y.flags['F_CONTIGUOUS']
- True
-
- Note: This function returns an array with at least one-dimension (1-d)
- so it will not preserve 0-d arrays.
-
- """
- if like is not None:
- return _asfortranarray_with_like(a, dtype=dtype, like=like)
-
- return array(a, dtype, copy=False, order='F', ndmin=1)
-
-
-_asfortranarray_with_like = array_function_dispatch(
- _asarray_contiguous_fortran_dispatcher
-)(asfortranarray)
-
def _require_dispatcher(a, dtype=None, requirements=None, *, like=None):
return (like,)
diff --git a/numpy/core/_asarray.pyi b/numpy/core/_asarray.pyi
index 8c200ba22..ee21fc0f1 100644
--- a/numpy/core/_asarray.pyi
+++ b/numpy/core/_asarray.pyi
@@ -11,6 +11,10 @@ else:
_ArrayType = TypeVar("_ArrayType", bound=ndarray)
+# TODO: The following functions are now defined in C, so should be defined
+# in a (not yet existing) `multiarray.pyi`.
+# (with the exception of `require`)
+
def asarray(
a: object,
dtype: DTypeLike = ...,
diff --git a/numpy/core/_methods.py b/numpy/core/_methods.py
index 09147fe5b..e475b94df 100644
--- a/numpy/core/_methods.py
+++ b/numpy/core/_methods.py
@@ -8,7 +8,7 @@ from contextlib import nullcontext
from numpy.core import multiarray as mu
from numpy.core import umath as um
-from numpy.core._asarray import asanyarray
+from numpy.core.multiarray import asanyarray
from numpy.core import numerictypes as nt
from numpy.core import _exceptions
from numpy._globals import _NoValue
diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py
index bb736d1a0..3646b39b0 100644
--- a/numpy/core/fromnumeric.py
+++ b/numpy/core/fromnumeric.py
@@ -10,8 +10,7 @@ from . import multiarray as mu
from . import overrides
from . import umath as um
from . import numerictypes as nt
-from ._asarray import asarray, array, asanyarray
-from .multiarray import concatenate
+from .multiarray import asarray, array, asanyarray, concatenate
from . import _methods
_dt_ = nt.sctype2char
diff --git a/numpy/core/multiarray.py b/numpy/core/multiarray.py
index b7277ac24..b7a3a8d67 100644
--- a/numpy/core/multiarray.py
+++ b/numpy/core/multiarray.py
@@ -26,7 +26,8 @@ __all__ = [
'MAY_SHARE_BOUNDS', 'MAY_SHARE_EXACT', 'NEEDS_INIT', 'NEEDS_PYAPI',
'RAISE', 'USE_GETITEM', 'USE_SETITEM', 'WRAP', '_fastCopyAndTranspose',
'_flagdict', '_insert', '_reconstruct', '_vec_string', '_monotonicity',
- 'add_docstring', 'arange', 'array', 'bincount', 'broadcast',
+ 'add_docstring', 'arange', 'array', 'asarray', 'asanyarray',
+ 'ascontiguousarray', 'asfortranarray', 'bincount', 'broadcast',
'busday_count', 'busday_offset', 'busdaycalendar', 'can_cast',
'compare_chararrays', 'concatenate', 'copyto', 'correlate', 'correlate2',
'count_nonzero', 'c_einsum', 'datetime_as_string', 'datetime_data',
@@ -49,6 +50,10 @@ scalar.__module__ = 'numpy.core.multiarray'
arange.__module__ = 'numpy'
array.__module__ = 'numpy'
+asarray.__module__ = 'numpy'
+asanyarray.__module__ = 'numpy'
+ascontiguousarray.__module__ = 'numpy'
+asfortranarray.__module__ = 'numpy'
datetime_data.__module__ = 'numpy'
empty.__module__ = 'numpy'
frombuffer.__module__ = 'numpy'
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py
index a6ee9eba9..8bb37e291 100644
--- a/numpy/core/numeric.py
+++ b/numpy/core/numeric.py
@@ -10,7 +10,8 @@ from . import multiarray
from .multiarray import (
_fastCopyAndTranspose as fastCopyAndTranspose, ALLOW_THREADS,
BUFSIZE, CLIP, MAXDIMS, MAY_SHARE_BOUNDS, MAY_SHARE_EXACT, RAISE,
- WRAP, arange, array, broadcast, can_cast, compare_chararrays,
+ WRAP, arange, array, asarray, asanyarray, ascontiguousarray,
+ asfortranarray, broadcast, can_cast, compare_chararrays,
concatenate, copyto, dot, dtype, empty,
empty_like, flatiter, frombuffer, fromfile, fromiter, fromstring,
inner, lexsort, matmul, may_share_memory,
@@ -26,7 +27,6 @@ from .umath import (multiply, invert, sin, PINF, NAN)
from . import numerictypes
from .numerictypes import longlong, intc, int_, float_, complex_, bool_
from ._exceptions import TooHardError, AxisError
-from ._asarray import asarray, asanyarray
from ._ufunc_config import errstate
bitwise_not = invert
@@ -39,7 +39,8 @@ array_function_dispatch = functools.partial(
__all__ = [
'newaxis', 'ndarray', 'flatiter', 'nditer', 'nested_iters', 'ufunc',
- 'arange', 'array', 'zeros', 'count_nonzero', 'empty', 'broadcast', 'dtype',
+ 'arange', 'array', 'asarray', 'asanyarray', 'ascontiguousarray',
+ 'asfortranarray', 'zeros', 'count_nonzero', 'empty', 'broadcast', 'dtype',
'fromstring', 'fromfile', 'frombuffer', 'where',
'argwhere', 'copyto', 'concatenate', 'fastCopyAndTranspose', 'lexsort',
'set_numeric_ops', 'can_cast', 'promote_types', 'min_scalar_type',
@@ -2349,7 +2350,7 @@ def isclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):
# Although, the default tolerances are unlikely to be useful
if y.dtype.kind != "m":
dt = multiarray.result_type(y, 1.)
- y = array(y, dtype=dt, copy=False, subok=True)
+ y = asanyarray(y, dtype=dt)
xfin = isfinite(x)
yfin = isfinite(y)
diff --git a/numpy/core/shape_base.py b/numpy/core/shape_base.py
index 89e98ab30..a81a04f7f 100644
--- a/numpy/core/shape_base.py
+++ b/numpy/core/shape_base.py
@@ -8,8 +8,7 @@ import warnings
from . import numeric as _nx
from . import overrides
-from ._asarray import array, asanyarray
-from .multiarray import normalize_axis_index
+from .multiarray import array, asanyarray, normalize_axis_index
from . import fromnumeric as _from_nx
diff --git a/numpy/core/src/multiarray/arrayfunction_override.c b/numpy/core/src/multiarray/arrayfunction_override.c
index 2c07cdebc..31415e4f2 100644
--- a/numpy/core/src/multiarray/arrayfunction_override.c
+++ b/numpy/core/src/multiarray/arrayfunction_override.c
@@ -213,7 +213,7 @@ call_array_function(PyObject* argument, PyObject* method,
* to NotImplemented to indicate the default implementation should
* be used.
*/
-NPY_NO_EXPORT PyObject *
+static PyObject *
array_implement_array_function_internal(
PyObject *public_api, PyObject *relevant_args,
PyObject *args, PyObject *kwargs)
@@ -364,66 +364,101 @@ array_implement_array_function(
return res;
}
-
/*
* Implements the __array_function__ protocol for C array creation functions
* only. Added as an extension to NEP-18 in an effort to bring NEP-35 to
* life with minimal dispatch overhead.
+ *
+ * The caller must ensure that `like != NULL`.
*/
NPY_NO_EXPORT PyObject *
array_implement_c_array_function_creation(
- const char *function_name, PyObject *args, PyObject *kwargs)
+ const char *function_name, PyObject *like,
+ PyObject *args, PyObject *kwargs,
+ PyObject *const *fast_args, Py_ssize_t len_args, PyObject *kwnames)
{
- if (kwargs == NULL) {
- return Py_NotImplemented;
+ PyObject *relevant_args = NULL;
+ PyObject *numpy_module = NULL;
+ PyObject *public_api = NULL;
+ PyObject *result = NULL;
+
+ if (!get_array_function(like)) {
+ return PyErr_Format(PyExc_TypeError,
+ "The `like` argument must be an array-like that implements "
+ "the `__array_function__` protocol.");
}
- /* Remove `like=` kwarg, which is NumPy-exclusive and thus not present
- * in downstream libraries. If that key isn't present, return NULL and
- * let originating call to continue. If the key is present but doesn't
- * implement `__array_function__`, raise a `TypeError`.
- */
- if (!PyDict_Contains(kwargs, npy_ma_str_like)) {
- return Py_NotImplemented;
+ if (fast_args != NULL) {
+ /*
+ * Convert from vectorcall convention, since the protocol requires
+ * the normal convention. We have to do this late to ensure the
+ * normal path where NotImplemented is returned is fast.
+ */
+ assert(args == NULL);
+ assert(kwargs == NULL);
+ args = PyTuple_New(len_args);
+ if (args == NULL) {
+ return NULL;
+ }
+ for (Py_ssize_t i = 0; i < len_args; i++) {
+ Py_INCREF(fast_args[i]);
+ PyTuple_SET_ITEM(args, i, fast_args[i]);
+ }
+ if (kwnames != NULL) {
+ kwargs = PyDict_New();
+ if (kwargs == NULL) {
+ Py_DECREF(args);
+ return NULL;
+ }
+ Py_ssize_t nkwargs = PyTuple_GET_SIZE(kwnames);
+ for (Py_ssize_t i = 0; i < nkwargs; i++) {
+ PyObject *key = PyTuple_GET_ITEM(kwnames, i);
+ PyObject *value = fast_args[i+len_args];
+ if (PyDict_SetItem(kwargs, key, value) < 0) {
+ Py_DECREF(args);
+ Py_DECREF(kwargs);
+ return NULL;
+ }
+ }
+ }
}
- PyObject *like_arg = PyDict_GetItem(kwargs, npy_ma_str_like);
- if (like_arg == NULL) {
- return NULL;
+ relevant_args = PyTuple_Pack(1, like);
+ if (relevant_args == NULL) {
+ goto finish;
}
- else if (!get_array_function(like_arg)) {
- return PyErr_Format(PyExc_TypeError,
- "The `like` argument must be an array-like that implements "
- "the `__array_function__` protocol.");
+ /* The like argument must be present in the keyword arguments, remove it */
+ if (PyDict_DelItem(kwargs, npy_ma_str_like) < 0) {
+ goto finish;
}
- PyObject *relevant_args = PyTuple_Pack(1, like_arg);
- PyDict_DelItem(kwargs, npy_ma_str_like);
- PyObject *numpy_module = PyImport_Import(npy_ma_str_numpy);
+ numpy_module = PyImport_Import(npy_ma_str_numpy);
if (numpy_module == NULL) {
- Py_DECREF(relevant_args);
- return NULL;
+ goto finish;
}
- PyObject *public_api = PyObject_GetAttrString(numpy_module, function_name);
+ public_api = PyObject_GetAttrString(numpy_module, function_name);
Py_DECREF(numpy_module);
if (public_api == NULL) {
- Py_DECREF(relevant_args);
- return NULL;
+ goto finish;
}
if (!PyCallable_Check(public_api)) {
- Py_DECREF(relevant_args);
- Py_DECREF(public_api);
- return PyErr_Format(PyExc_RuntimeError,
- "numpy.%s is not callable.",
- function_name);
+ PyErr_Format(PyExc_RuntimeError,
+ "numpy.%s is not callable.", function_name);
+ goto finish;
}
- PyObject* result = array_implement_array_function_internal(
+ result = array_implement_array_function_internal(
public_api, relevant_args, args, kwargs);
- Py_DECREF(relevant_args);
- Py_DECREF(public_api);
+ finish:
+ if (kwnames != NULL) {
+ /* args and kwargs were converted from vectorcall convention */
+ Py_XDECREF(args);
+ Py_XDECREF(kwargs);
+ }
+ Py_XDECREF(relevant_args);
+ Py_XDECREF(public_api);
return result;
}
diff --git a/numpy/core/src/multiarray/arrayfunction_override.h b/numpy/core/src/multiarray/arrayfunction_override.h
index fdcf1746d..fdf0dfcaf 100644
--- a/numpy/core/src/multiarray/arrayfunction_override.h
+++ b/numpy/core/src/multiarray/arrayfunction_override.h
@@ -11,7 +11,9 @@ array__get_implementing_args(
NPY_NO_EXPORT PyObject *
array_implement_c_array_function_creation(
- const char *function_name, PyObject *args, PyObject *kwargs);
+ const char *function_name, PyObject *like,
+ PyObject *args, PyObject *kwargs,
+ PyObject *const *fast_args, Py_ssize_t len_args, PyObject *kwnames);
NPY_NO_EXPORT PyObject *
array_function_method_impl(PyObject *func, PyObject *types, PyObject *args,
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c
index 12705dc19..953e2b4cf 100644
--- a/numpy/core/src/multiarray/multiarraymodule.c
+++ b/numpy/core/src/multiarray/multiarraymodule.c
@@ -1556,135 +1556,23 @@ _prepend_ones(PyArrayObject *arr, int nd, int ndmin, NPY_ORDER order)
((order) == NPY_CORDER && PyArray_IS_C_CONTIGUOUS(op)) || \
((order) == NPY_FORTRANORDER && PyArray_IS_F_CONTIGUOUS(op)))
-static PyObject *
-_array_fromobject(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kws)
+static NPY_INLINE PyObject *
+_array_fromobject_generic(
+ PyObject *op, PyArray_Descr *type, npy_bool copy, NPY_ORDER order,
+ npy_bool subok, int ndmin)
{
- PyObject *op;
PyArrayObject *oparr = NULL, *ret = NULL;
- npy_bool subok = NPY_FALSE;
- npy_bool copy = NPY_TRUE;
- int ndmin = 0, nd;
- PyObject* like;
- PyArray_Descr *type = NULL;
PyArray_Descr *oldtype = NULL;
- NPY_ORDER order = NPY_KEEPORDER;
- int flags = 0;
-
- PyObject* array_function_result = NULL;
-
- static char *kwd[] = {"object", "dtype", "copy", "order", "subok",
- "ndmin", "like", NULL};
-
- if (PyTuple_GET_SIZE(args) > 2) {
- PyErr_Format(PyExc_TypeError,
- "array() takes from 1 to 2 positional arguments but "
- "%zd were given", PyTuple_GET_SIZE(args));
- return NULL;
- }
-
- array_function_result = array_implement_c_array_function_creation(
- "array", args, kws);
- if (array_function_result != Py_NotImplemented) {
- return array_function_result;
- }
-
- /* super-fast path for ndarray argument calls */
- if (PyTuple_GET_SIZE(args) == 0) {
- goto full_path;
- }
- op = PyTuple_GET_ITEM(args, 0);
- if (PyArray_CheckExact(op)) {
- PyObject * dtype_obj = Py_None;
- oparr = (PyArrayObject *)op;
- /* get dtype which can be positional */
- if (PyTuple_GET_SIZE(args) == 2) {
- dtype_obj = PyTuple_GET_ITEM(args, 1);
- }
- else if (kws) {
- dtype_obj = PyDict_GetItemWithError(kws, npy_ma_str_dtype);
- if (dtype_obj == NULL && PyErr_Occurred()) {
- return NULL;
- }
- if (dtype_obj == NULL) {
- dtype_obj = Py_None;
- }
- }
- if (dtype_obj != Py_None) {
- goto full_path;
- }
-
- /* array(ndarray) */
- if (kws == NULL) {
- ret = (PyArrayObject *)PyArray_NewCopy(oparr, order);
- goto finish;
- }
- else {
- /* fast path for copy=False rest default (np.asarray) */
- PyObject * copy_obj, * order_obj, *ndmin_obj;
- copy_obj = PyDict_GetItemWithError(kws, npy_ma_str_copy);
- if (copy_obj == NULL && PyErr_Occurred()) {
- return NULL;
- }
- if (copy_obj != Py_False) {
- goto full_path;
- }
- copy = NPY_FALSE;
-
- /* order does not matter for contiguous 1d arrays */
- if (PyArray_NDIM((PyArrayObject*)op) > 1 ||
- !PyArray_IS_C_CONTIGUOUS((PyArrayObject*)op)) {
- order_obj = PyDict_GetItemWithError(kws, npy_ma_str_order);
- if (order_obj == NULL && PyErr_Occurred()) {
- return NULL;
- }
- else if (order_obj != Py_None && order_obj != NULL) {
- goto full_path;
- }
- }
-
- ndmin_obj = PyDict_GetItemWithError(kws, npy_ma_str_ndmin);
- if (ndmin_obj == NULL && PyErr_Occurred()) {
- return NULL;
- }
- else if (ndmin_obj) {
- long t = PyLong_AsLong(ndmin_obj);
- if (error_converting(t)) {
- goto clean_type;
- }
- else if (t > NPY_MAXDIMS) {
- goto full_path;
- }
- ndmin = t;
- }
-
- /* copy=False with default dtype, order (any is OK) and ndim */
- ret = oparr;
- Py_INCREF(ret);
- goto finish;
- }
- }
-
-full_path:
- if (!PyArg_ParseTupleAndKeywords(args, kws, "O|O&O&O&O&i$O:array", kwd,
- &op,
- PyArray_DescrConverter2, &type,
- PyArray_BoolConverter, &copy,
- PyArray_OrderConverter, &order,
- PyArray_BoolConverter, &subok,
- &ndmin,
- &like)) {
- goto clean_type;
- }
+ int nd, flags = 0;
if (ndmin > NPY_MAXDIMS) {
PyErr_Format(PyExc_ValueError,
"ndmin bigger than allowable number of dimensions "
"NPY_MAXDIMS (=%d)", NPY_MAXDIMS);
- goto clean_type;
+ return NULL;
}
/* fast exit if simple call */
- if ((subok && PyArray_Check(op)) ||
- (!subok && PyArray_CheckExact(op))) {
+ if (PyArray_CheckExact(op) || (subok && PyArray_Check(op))) {
oparr = (PyArrayObject *)op;
if (type == NULL) {
if (!copy && STRIDING_OK(oparr, order)) {
@@ -1739,8 +1627,7 @@ full_path:
ret = (PyArrayObject *)PyArray_CheckFromAny(op, type,
0, 0, flags, NULL);
- finish:
- Py_XDECREF(type);
+finish:
if (ret == NULL) {
return NULL;
}
@@ -1754,16 +1641,215 @@ full_path:
* steals a reference to ret
*/
return _prepend_ones(ret, nd, ndmin, order);
+}
+
+#undef STRIDING_OK
+
-clean_type:
+static PyObject *
+array_array(PyObject *NPY_UNUSED(ignored),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
+{
+ PyObject *op;
+ npy_bool subok = NPY_FALSE;
+ npy_bool copy = NPY_TRUE;
+ int ndmin = 0;
+ PyArray_Descr *type = NULL;
+ NPY_ORDER order = NPY_KEEPORDER;
+ PyObject *like = NULL;
+ NPY_PREPARE_ARGPARSER;
+
+ if (len_args != 1 || (kwnames != NULL)) {
+ if (npy_parse_arguments("array", args, len_args, kwnames,
+ "object", NULL, &op,
+ "|dtype", &PyArray_DescrConverter2, &type,
+ "$copy", &PyArray_BoolConverter, &copy,
+ "$order", &PyArray_OrderConverter, &order,
+ "$subok", &PyArray_BoolConverter, &subok,
+ "$ndmin", &PyArray_PythonPyIntFromInt, &ndmin,
+ "$like", NULL, &like,
+ NULL, NULL, NULL) < 0) {
+ Py_XDECREF(type);
+ return NULL;
+ }
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "array", like, NULL, NULL, args, len_args, kwnames);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(type);
+ return deferred;
+ }
+ }
+ }
+ else {
+ /* Fast path for symmetry (we copy by default which is slow) */
+ op = args[0];
+ }
+
+ PyObject *res = _array_fromobject_generic(
+ op, type, copy, order, subok, ndmin);
Py_XDECREF(type);
- return NULL;
+ return res;
}
static PyObject *
-array_copyto(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds)
+array_asarray(PyObject *NPY_UNUSED(ignored),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
+{
+ PyObject *op;
+ PyArray_Descr *type = NULL;
+ NPY_ORDER order = NPY_KEEPORDER;
+ PyObject *like = NULL;
+ NPY_PREPARE_ARGPARSER;
+
+ if (len_args != 1 || (kwnames != NULL)) {
+ if (npy_parse_arguments("asarray", args, len_args, kwnames,
+ "a", NULL, &op,
+ "|dtype", &PyArray_DescrConverter2, &type,
+ "|order", &PyArray_OrderConverter, &order,
+ "$like", NULL, &like,
+ NULL, NULL, NULL) < 0) {
+ Py_XDECREF(type);
+ return NULL;
+ }
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "asarray", like, NULL, NULL, args, len_args, kwnames);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(type);
+ return deferred;
+ }
+ }
+ }
+ else {
+ op = args[0];
+ }
+
+ PyObject *res = _array_fromobject_generic(
+ op, type, NPY_FALSE, order, NPY_FALSE, 0);
+ Py_XDECREF(type);
+ return res;
+}
+
+static PyObject *
+array_asanyarray(PyObject *NPY_UNUSED(ignored),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
+{
+ PyObject *op;
+ PyArray_Descr *type = NULL;
+ NPY_ORDER order = NPY_KEEPORDER;
+ PyObject *like = NULL;
+ NPY_PREPARE_ARGPARSER;
+
+ if (len_args != 1 || (kwnames != NULL)) {
+ if (npy_parse_arguments("asanyarray", args, len_args, kwnames,
+ "a", NULL, &op,
+ "|dtype", &PyArray_DescrConverter2, &type,
+ "|order", &PyArray_OrderConverter, &order,
+ "$like", NULL, &like,
+ NULL, NULL, NULL) < 0) {
+ Py_XDECREF(type);
+ return NULL;
+ }
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "asanyarray", like, NULL, NULL, args, len_args, kwnames);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(type);
+ return deferred;
+ }
+ }
+ }
+ else {
+ op = args[0];
+ }
+
+ PyObject *res = _array_fromobject_generic(
+ op, type, NPY_FALSE, order, NPY_TRUE, 0);
+ Py_XDECREF(type);
+ return res;
+}
+
+
+static PyObject *
+array_ascontiguousarray(PyObject *NPY_UNUSED(ignored),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
+{
+ PyObject *op;
+ PyArray_Descr *type = NULL;
+ PyObject *like = NULL;
+ NPY_PREPARE_ARGPARSER;
+
+ if (len_args != 1 || (kwnames != NULL)) {
+ if (npy_parse_arguments("ascontiguousarray", args, len_args, kwnames,
+ "a", NULL, &op,
+ "|dtype", &PyArray_DescrConverter2, &type,
+ "$like", NULL, &like,
+ NULL, NULL, NULL) < 0) {
+ Py_XDECREF(type);
+ return NULL;
+ }
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "ascontiguousarray", like, NULL, NULL, args, len_args, kwnames);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(type);
+ return deferred;
+ }
+ }
+ }
+ else {
+ op = args[0];
+ }
+
+ PyObject *res = _array_fromobject_generic(
+ op, type, NPY_FALSE, NPY_CORDER, NPY_FALSE, 1);
+ Py_XDECREF(type);
+ return res;
+}
+
+
+static PyObject *
+array_asfortranarray(PyObject *NPY_UNUSED(ignored),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
+ PyObject *op;
+ PyArray_Descr *type = NULL;
+ PyObject *like = NULL;
+ NPY_PREPARE_ARGPARSER;
+
+ if (len_args != 1 || (kwnames != NULL)) {
+ if (npy_parse_arguments("asfortranarray", args, len_args, kwnames,
+ "a", NULL, &op,
+ "|dtype", &PyArray_DescrConverter2, &type,
+ "$like", NULL, &like,
+ NULL, NULL, NULL) < 0) {
+ Py_XDECREF(type);
+ return NULL;
+ }
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "asfortranarray", like, NULL, NULL, args, len_args, kwnames);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(type);
+ return deferred;
+ }
+ }
+ }
+ else {
+ op = args[0];
+ }
+
+ PyObject *res = _array_fromobject_generic(
+ op, type, NPY_FALSE, NPY_FORTRANORDER, NPY_FALSE, 1);
+ Py_XDECREF(type);
+ return res;
+}
+
+static PyObject *
+array_copyto(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds)
+{
static char *kwlist[] = {"dst", "src", "casting", "where", NULL};
PyObject *wheremask_in = NULL;
PyArrayObject *dst = NULL, *src = NULL, *wheremask = NULL;
@@ -1806,32 +1892,34 @@ fail:
}
static PyObject *
-array_empty(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds)
+array_empty(PyObject *NPY_UNUSED(ignored),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
-
- static char *kwlist[] = {"shape", "dtype", "order", "like", NULL};
PyArray_Descr *typecode = NULL;
PyArray_Dims shape = {NULL, 0};
NPY_ORDER order = NPY_CORDER;
- PyObject *like = NULL;
npy_bool is_f_order;
- PyObject *array_function_result = NULL;
PyArrayObject *ret = NULL;
+ PyObject *like = NULL;
+ NPY_PREPARE_ARGPARSER;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O&O&$O:empty", kwlist,
- PyArray_IntpConverter, &shape,
- PyArray_DescrConverter, &typecode,
- PyArray_OrderConverter, &order,
- &like)) {
+ if (npy_parse_arguments("empty", args, len_args, kwnames,
+ "shape", &PyArray_IntpConverter, &shape,
+ "|dtype", &PyArray_DescrConverter, &typecode,
+ "|order", &PyArray_OrderConverter, &order,
+ "$like", NULL, &like,
+ NULL, NULL, NULL) < 0) {
goto fail;
}
- array_function_result = array_implement_c_array_function_creation(
- "empty", args, kwds);
- if (array_function_result != Py_NotImplemented) {
- Py_XDECREF(typecode);
- npy_free_cache_dim_obj(shape);
- return array_function_result;
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "empty", like, NULL, NULL, args, len_args, kwnames);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(typecode);
+ npy_free_cache_dim_obj(shape);
+ return deferred;
+ }
}
switch (order) {
@@ -2006,31 +2094,35 @@ array_scalar(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds)
}
static PyObject *
-array_zeros(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds)
+array_zeros(PyObject *NPY_UNUSED(ignored),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
- static char *kwlist[] = {"shape", "dtype", "order", "like", NULL};
PyArray_Descr *typecode = NULL;
PyArray_Dims shape = {NULL, 0};
NPY_ORDER order = NPY_CORDER;
- PyObject *like = NULL;
npy_bool is_f_order = NPY_FALSE;
- PyObject *array_function_result = NULL;
PyArrayObject *ret = NULL;
+ PyObject *like = NULL;
+ NPY_PREPARE_ARGPARSER;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O&O&$O:zeros", kwlist,
- PyArray_IntpConverter, &shape,
- PyArray_DescrConverter, &typecode,
- PyArray_OrderConverter, &order,
- &like)) {
+ if (npy_parse_arguments("zeros", args, len_args, kwnames,
+ "shape", &PyArray_IntpConverter, &shape,
+ "|dtype", &PyArray_DescrConverter, &typecode,
+ "|order", &PyArray_OrderConverter, &order,
+ "$like", NULL, &like,
+ NULL, NULL, NULL) < 0) {
goto fail;
}
- array_function_result = array_implement_c_array_function_creation(
- "zeros", args, kwds);
- if (array_function_result != Py_NotImplemented) {
- Py_XDECREF(typecode);
- npy_free_cache_dim_obj(shape);
- return array_function_result;
+
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "zeros", like, NULL, NULL, args, len_args, kwnames);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(typecode);
+ npy_free_cache_dim_obj(shape);
+ return deferred;
+ }
}
switch (order) {
@@ -2088,7 +2180,6 @@ array_fromstring(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds
static char *kwlist[] = {"string", "dtype", "count", "sep", "like", NULL};
PyObject *like = NULL;
PyArray_Descr *descr = NULL;
- PyObject *array_function_result = NULL;
if (!PyArg_ParseTupleAndKeywords(args, keywds,
"s#|O&" NPY_SSIZE_T_PYFMT "s$O:fromstring", kwlist,
@@ -2096,11 +2187,13 @@ array_fromstring(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds
Py_XDECREF(descr);
return NULL;
}
-
- array_function_result = array_implement_c_array_function_creation(
- "fromstring", args, keywds);
- if (array_function_result != Py_NotImplemented) {
- return array_function_result;
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "fromstring", like, args, keywds, NULL, 0, NULL);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(descr);
+ return deferred;
+ }
}
/* binary mode, condition copied from PyArray_FromString */
@@ -2128,7 +2221,6 @@ array_fromfile(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds)
static char *kwlist[] = {"file", "dtype", "count", "sep", "offset", "like", NULL};
PyObject *like = NULL;
PyArray_Descr *type = NULL;
- PyObject *array_function_result = NULL;
int own;
npy_off_t orig_pos = 0, offset = 0;
FILE *fp;
@@ -2140,11 +2232,13 @@ array_fromfile(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds)
return NULL;
}
- array_function_result = array_implement_c_array_function_creation(
- "fromfile", args, keywds);
- if (array_function_result != Py_NotImplemented) {
- Py_XDECREF(type);
- return array_function_result;
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "fromfile", like, args, keywds, NULL, 0, NULL);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(type);
+ return deferred;
+ }
}
file = NpyPath_PathlikeToFspath(file);
@@ -2217,7 +2311,6 @@ array_fromiter(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds)
static char *kwlist[] = {"iter", "dtype", "count", "like", NULL};
PyObject *like = NULL;
PyArray_Descr *descr = NULL;
- PyObject *array_function_result = NULL;
if (!PyArg_ParseTupleAndKeywords(args, keywds,
"OO&|" NPY_SSIZE_T_PYFMT "$O:fromiter", kwlist,
@@ -2225,12 +2318,13 @@ array_fromiter(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds)
Py_XDECREF(descr);
return NULL;
}
-
- array_function_result = array_implement_c_array_function_creation(
- "fromiter", args, keywds);
- if (array_function_result != Py_NotImplemented) {
- Py_DECREF(descr);
- return array_function_result;
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "fromiter", like, args, keywds, NULL, 0, NULL);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(descr);
+ return deferred;
+ }
}
return PyArray_FromIter(iter, descr, (npy_intp)nin);
@@ -2244,7 +2338,6 @@ array_frombuffer(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds
static char *kwlist[] = {"buffer", "dtype", "count", "offset", "like", NULL};
PyObject *like = NULL;
PyArray_Descr *type = NULL;
- PyObject *array_function_result = NULL;
if (!PyArg_ParseTupleAndKeywords(args, keywds,
"O|O&" NPY_SSIZE_T_PYFMT NPY_SSIZE_T_PYFMT "$O:frombuffer", kwlist,
@@ -2253,11 +2346,13 @@ array_frombuffer(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds
return NULL;
}
- array_function_result = array_implement_c_array_function_creation(
- "frombuffer", args, keywds);
- if (array_function_result != Py_NotImplemented) {
- Py_XDECREF(type);
- return array_function_result;
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "frombuffer", like, args, keywds, NULL, 0, NULL);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(type);
+ return deferred;
+ }
}
if (type == NULL) {
@@ -2865,25 +2960,35 @@ array_correlate2(PyObject *NPY_UNUSED(dummy),
}
static PyObject *
-array_arange(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kws) {
+array_arange(PyObject *NPY_UNUSED(ignored),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
+{
PyObject *o_start = NULL, *o_stop = NULL, *o_step = NULL, *range=NULL;
- PyObject *like = NULL;
- PyObject *array_function_result = NULL;
- static char *kwd[] = {"start", "stop", "step", "dtype", "like", NULL};
PyArray_Descr *typecode = NULL;
+ PyObject *like = NULL;
+ NPY_PREPARE_ARGPARSER;
- if (!PyArg_ParseTupleAndKeywords(args, kws, "|OOOO&$O:arange", kwd,
- &o_start,
- &o_stop,
- &o_step,
- PyArray_DescrConverter2, &typecode,
- &like)) {
+ if (npy_parse_arguments("arange", args, len_args, kwnames,
+ "|start", NULL, &o_start,
+ "|stop", NULL, &o_stop,
+ "|step", NULL, &o_step,
+ "|dtype", &PyArray_DescrConverter2, &typecode,
+ "$like", NULL, &like,
+ NULL, NULL, NULL) < 0) {
Py_XDECREF(typecode);
return NULL;
}
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "arange", like, NULL, NULL, args, len_args, kwnames);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(typecode);
+ return deferred;
+ }
+ }
if (o_stop == NULL) {
- if (args == NULL || PyTuple_GET_SIZE(args) == 0){
+ if (len_args == 0){
PyErr_SetString(PyExc_TypeError,
"arange() requires stop to be specified.");
Py_XDECREF(typecode);
@@ -2895,13 +3000,6 @@ array_arange(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kws) {
o_stop = NULL;
}
- array_function_result = array_implement_c_array_function_creation(
- "arange", args, kws);
- if (array_function_result != Py_NotImplemented) {
- Py_XDECREF(typecode);
- return array_function_result;
- }
-
range = PyArray_ArangeObj(o_start, o_stop, o_step, typecode);
Py_XDECREF(typecode);
@@ -4149,8 +4247,20 @@ static struct PyMethodDef array_module_methods[] = {
(PyCFunction)array_set_typeDict,
METH_VARARGS, NULL},
{"array",
- (PyCFunction)_array_fromobject,
- METH_VARARGS|METH_KEYWORDS, NULL},
+ (PyCFunction)array_array,
+ METH_FASTCALL | METH_KEYWORDS, NULL},
+ {"asarray",
+ (PyCFunction)array_asarray,
+ METH_FASTCALL | METH_KEYWORDS, NULL},
+ {"asanyarray",
+ (PyCFunction)array_asanyarray,
+ METH_FASTCALL | METH_KEYWORDS, NULL},
+ {"ascontiguousarray",
+ (PyCFunction)array_ascontiguousarray,
+ METH_FASTCALL | METH_KEYWORDS, NULL},
+ {"asfortranarray",
+ (PyCFunction)array_asfortranarray,
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"copyto",
(PyCFunction)array_copyto,
METH_VARARGS|METH_KEYWORDS, NULL},
@@ -4159,16 +4269,16 @@ static struct PyMethodDef array_module_methods[] = {
METH_VARARGS|METH_KEYWORDS, NULL},
{"arange",
(PyCFunction)array_arange,
- METH_VARARGS|METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"zeros",
(PyCFunction)array_zeros,
- METH_VARARGS|METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"count_nonzero",
(PyCFunction)array_count_nonzero,
METH_VARARGS|METH_KEYWORDS, NULL},
{"empty",
(PyCFunction)array_empty,
- METH_VARARGS|METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"empty_like",
(PyCFunction)array_empty_like,
METH_VARARGS|METH_KEYWORDS, NULL},
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index ddd0e31c5..269e144d9 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -484,6 +484,33 @@ class TestArrayConstruction:
assert_(np.ascontiguousarray(d).flags.c_contiguous)
assert_(np.asfortranarray(d).flags.f_contiguous)
+ @pytest.mark.parametrize("func",
+ [np.array,
+ np.asarray,
+ np.asanyarray,
+ np.ascontiguousarray,
+ np.asfortranarray])
+ def test_bad_arguments_error(self, func):
+ with pytest.raises(TypeError):
+ func(3, dtype="bad dtype")
+ with pytest.raises(TypeError):
+ func() # missing arguments
+ with pytest.raises(TypeError):
+ func(1, 2, 3, 4, 5, 6, 7, 8) # too many arguments
+
+ @pytest.mark.parametrize("func",
+ [np.array,
+ np.asarray,
+ np.asanyarray,
+ np.ascontiguousarray,
+ np.asfortranarray])
+ def test_array_as_keyword(self, func):
+ # This should likely be made positional only, but do not change
+ # the name accidentally.
+ if func is np.array:
+ func(object=3)
+ else:
+ func(a=3)
class TestAssignment:
def test_assignment_broadcasting(self):
diff --git a/numpy/core/tests/test_overrides.py b/numpy/core/tests/test_overrides.py
index 6862fca03..0809e1e92 100644
--- a/numpy/core/tests/test_overrides.py
+++ b/numpy/core/tests/test_overrides.py
@@ -577,5 +577,6 @@ class TestArrayLike:
ref = self.MyArray.array()
- with assert_raises(ValueError):
+ with assert_raises(TypeError):
+ # Raises the error about `value_error` being invalid first
np.array(1, value_error=True, like=ref)
diff --git a/numpy/ctypeslib.py b/numpy/ctypeslib.py
index dbc683a6b..8ba6f15e5 100644
--- a/numpy/ctypeslib.py
+++ b/numpy/ctypeslib.py
@@ -54,7 +54,7 @@ __all__ = ['load_library', 'ndpointer', 'c_intp', 'as_ctypes', 'as_array',
import os
from numpy import (
- integer, ndarray, dtype as _dtype, array, frombuffer
+ integer, ndarray, dtype as _dtype, asarray, frombuffer
)
from numpy.core.multiarray import _flagdict, flagsobj
@@ -515,7 +515,7 @@ if ctypes is not None:
p_arr_type = ctypes.POINTER(_ctype_ndarray(obj._type_, shape))
obj = ctypes.cast(obj, p_arr_type).contents
- return array(obj, copy=False)
+ return asarray(obj)
def as_ctypes(obj):
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py
index c6db42ce4..44eac31ef 100644
--- a/numpy/lib/function_base.py
+++ b/numpy/lib/function_base.py
@@ -593,7 +593,7 @@ def piecewise(x, condlist, funclist, *args, **kw):
not isinstance(condlist[0], (list, ndarray)) and x.ndim != 0):
condlist = [condlist]
- condlist = array(condlist, dtype=bool)
+ condlist = asarray(condlist, dtype=bool)
n = len(condlist)
if n == n2 - 1: # compute the "otherwise" condition.
@@ -2191,15 +2191,14 @@ class vectorize:
ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args)
# Convert args to object arrays first
- inputs = [array(a, copy=False, subok=True, dtype=object)
- for a in args]
+ inputs = [asanyarray(a, dtype=object) for a in args]
outputs = ufunc(*inputs)
if ufunc.nout == 1:
- res = array(outputs, copy=False, subok=True, dtype=otypes[0])
+ res = asanyarray(outputs, dtype=otypes[0])
else:
- res = tuple([array(x, copy=False, subok=True, dtype=t)
+ res = tuple([asanyarray(x, dtype=t)
for x, t in zip(outputs, otypes)])
return res
diff --git a/numpy/lib/shape_base.py b/numpy/lib/shape_base.py
index d19bfb8f8..a3fbee3d5 100644
--- a/numpy/lib/shape_base.py
+++ b/numpy/lib/shape_base.py
@@ -649,7 +649,7 @@ def column_stack(tup):
arrays = []
for v in tup:
- arr = array(v, copy=False, subok=True)
+ arr = asanyarray(v)
if arr.ndim < 2:
arr = array(arr, copy=False, subok=True, ndmin=2).T
arrays.append(arr)
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
index cebacf5e1..14dc21804 100644
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -3895,7 +3895,7 @@ class MaskedArray(ndarray):
# Force the condition to a regular ndarray and forget the missing
# values.
- condition = np.array(condition, copy=False, subok=False)
+ condition = np.asarray(condition)
_new = _data.compress(condition, axis=axis, out=out).view(type(self))
_new._update_from(self)
diff --git a/numpy/ma/testutils.py b/numpy/ma/testutils.py
index 8d55e1763..2dd479abe 100644
--- a/numpy/ma/testutils.py
+++ b/numpy/ma/testutils.py
@@ -134,8 +134,8 @@ def assert_equal(actual, desired, err_msg=''):
msg = build_err_msg([actual, desired],
err_msg, header='', names=('x', 'y'))
raise ValueError(msg)
- actual = np.array(actual, copy=False, subok=True)
- desired = np.array(desired, copy=False, subok=True)
+ actual = np.asanyarray(actual)
+ desired = np.asanyarray(desired)
(actual_dtype, desired_dtype) = (actual.dtype, desired.dtype)
if actual_dtype.char == "S" and desired_dtype.char == "S":
return _assert_equal_on_sequences(actual.tolist(),
diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py
index 5b87d0a06..1bdb00fd5 100644
--- a/numpy/testing/_private/utils.py
+++ b/numpy/testing/_private/utils.py
@@ -17,6 +17,7 @@ from unittest.case import SkipTest
from warnings import WarningMessage
import pprint
+import numpy as np
from numpy.core import(
intp, float32, empty, arange, array_repr, ndarray, isnat, array)
import numpy.linalg.lapack_lite
@@ -378,7 +379,8 @@ def assert_equal(actual, desired, err_msg='', verbose=True):
try:
isdesnat = isnat(desired)
isactnat = isnat(actual)
- dtypes_match = array(desired).dtype.type == array(actual).dtype.type
+ dtypes_match = (np.asarray(desired).dtype.type ==
+ np.asarray(actual).dtype.type)
if isdesnat and isactnat:
# If both are NaT (and have the same dtype -- datetime or
# timedelta) they are considered equal.
@@ -398,8 +400,8 @@ def assert_equal(actual, desired, err_msg='', verbose=True):
return # both nan, so equal
# handle signed zero specially for floats
- array_actual = array(actual)
- array_desired = array(desired)
+ array_actual = np.asarray(actual)
+ array_desired = np.asarray(desired)
if (array_actual.dtype.char in 'Mm' or
array_desired.dtype.char in 'Mm'):
# version 1.18
@@ -701,8 +703,8 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, header='',
__tracebackhide__ = True # Hide traceback for py.test
from numpy.core import array, array2string, isnan, inf, bool_, errstate, all, max, object_
- x = array(x, copy=False, subok=True)
- y = array(y, copy=False, subok=True)
+ x = np.asanyarray(x)
+ y = np.asanyarray(y)
# original array for output formatting
ox, oy = x, y
@@ -1033,7 +1035,7 @@ def assert_array_almost_equal(x, y, decimal=6, err_msg='', verbose=True):
# make sure y is an inexact type to avoid abs(MIN_INT); will cause
# casting of x later.
dtype = result_type(y, 1.)
- y = array(y, dtype=dtype, copy=False, subok=True)
+ y = np.asanyarray(y, dtype)
z = abs(x - y)
if not issubdtype(z.dtype, number):
@@ -1678,11 +1680,11 @@ def nulp_diff(x, y, dtype=None):
"""
import numpy as np
if dtype:
- x = np.array(x, dtype=dtype)
- y = np.array(y, dtype=dtype)
+ x = np.asarray(x, dtype=dtype)
+ y = np.asarray(y, dtype=dtype)
else:
- x = np.array(x)
- y = np.array(y)
+ x = np.asarray(x)
+ y = np.asarray(y)
t = np.common_type(x, y)
if np.iscomplexobj(x) or np.iscomplexobj(y):
@@ -1699,7 +1701,7 @@ def nulp_diff(x, y, dtype=None):
(x.shape, y.shape))
def _diff(rx, ry, vdt):
- diff = np.array(rx-ry, dtype=vdt)
+ diff = np.asarray(rx-ry, dtype=vdt)
return np.abs(diff)
rx = integer_repr(x)