Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitc0617ac

Browse files
authored
Merge pull request#25168 from mtsokol/asarray-copy-arg
API: Introduce ``copy`` argument for ``np.asarray`` [Array API]
2 parentsde22d8c +beb523c commitc0617ac

File tree

65 files changed

+369
-282
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+369
-282
lines changed

‎benchmarks/benchmarks/bench_array_coercion.py‎

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,33 +23,32 @@ def time_array_dtype_not_kwargs(self, array_like):
2323
np.array(array_like,self.int64)
2424

2525
deftime_array_no_copy(self,array_like):
26-
np.array(array_like,copy=False)
26+
np.array(array_like,copy=None)
2727

2828
deftime_array_subok(self,array_like):
2929
np.array(array_like,subok=True)
3030

3131
deftime_array_all_kwargs(self,array_like):
32-
np.array(array_like,dtype=self.int64,copy=False,order="F",
32+
np.array(array_like,dtype=self.int64,copy=None,order="F",
3333
subok=False,ndmin=2)
3434

3535
deftime_asarray(self,array_like):
3636
np.asarray(array_like)
3737

3838
deftime_asarray_dtype(self,array_like):
39-
np.array(array_like,dtype=self.int64)
39+
np.asarray(array_like,dtype=self.int64)
4040

4141
deftime_asarray_dtype(self,array_like):
42-
np.array(array_like,dtype=self.int64,order="F")
42+
np.asarray(array_like,dtype=self.int64,order="F")
4343

4444
deftime_asanyarray(self,array_like):
45-
np.asarray(array_like)
45+
np.asanyarray(array_like)
4646

4747
deftime_asanyarray_dtype(self,array_like):
48-
np.array(array_like,dtype=self.int64)
48+
np.asanyarray(array_like,dtype=self.int64)
4949

5050
deftime_asanyarray_dtype(self,array_like):
51-
np.array(array_like,dtype=self.int64,order="F")
51+
np.asanyarray(array_like,dtype=self.int64,order="F")
5252

5353
deftime_ascontiguousarray(self,array_like):
5454
np.ascontiguousarray(array_like)
55-
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
New ``copy`` keyword meaning for `numpy.array` and `numpy.asarray`
2+
------------------------------------------------------------------
3+
Now `numpy.array` and `numpy.asarray` support three values for ``copy`` parameter:
4+
* ``None`` - A copy will only be made if it is necessary.
5+
* ``True`` - Always make a copy.
6+
* ``False`` - Never make a copy. If a copy is required a ``ValueError`` is raised.
7+
8+
The meaning of ``False`` changed as it now raises an exception if a copy is needed.

‎doc/source/reference/array_api.rst‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -494,9 +494,6 @@ Creation functions differences
494494
* - Feature
495495
- Type
496496
- Notes
497-
* - ``copy`` keyword argument to ``asarray``
498-
- **Compatible**
499-
-
500497

501498
Elementwise functions differences
502499
---------------------------------

‎doc/source/reference/arrays.classes.rst‎

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -305,19 +305,30 @@ NumPy provides several hooks that classes can customize:
305305
..note::For ufuncs, it is hoped to eventually deprecate this method in
306306
favour of:func:`__array_ufunc__`.
307307

308-
..py:method::class.__array__([dtype])
309-
310-
If defined on an object, should return an ``ndarray``.
311-
This method is called by array-coercion functions like np.array()
312-
if an object implementing this interface is passed to those functions.
313-
Please refer to:ref:`Interoperability with NumPy<basics.interoperability>`
314-
for the protocol hierarchy, of which ``__array__`` is the oldest and least
315-
desirable.
316-
317-
..note::If a class (ndarray subclass or not) having the :func:`__array__`
318-
method is used as the output object of an:ref:`ufunc
319-
<ufuncs-output-type>`, results will *not* be written to the object
320-
returned by:func:`__array__`. This practice will return ``TypeError``.
308+
..py:method::class.__array__(dtype=None,copy=None)
309+
310+
If defined on an object, should return an ``ndarray``.
311+
This method is called by array-coercion functions like np.array()
312+
if an object implementing this interface is passed to those functions.
313+
The third-party implementations of ``__array__`` must take ``dtype`` and
314+
``copy`` keyword arguments, as ignoring them might break third-party code
315+
or NumPy itself.
316+
317+
- ``dtype`` is a data type of the returned array.
318+
- ``copy`` is an optional boolean that indicates whether a copy should be
319+
returned. For ``True`` a copy should always be made, for ``None`` only
320+
if required (e.g. due to passed ``dtype`` value), and for ``False`` a copy
321+
should never be made (if a copy is still required, an appropriate exception
322+
should be raised).
323+
324+
Please refer to:ref:`Interoperability with NumPy<basics.interoperability>`
325+
for the protocol hierarchy, of which ``__array__`` is the oldest and least
326+
desirable.
327+
328+
..note::If a class (ndarray subclass or not) having the :func:`__array__`
329+
method is used as the output object of an:ref:`ufunc
330+
<ufuncs-output-type>`, results will *not* be written to the object
331+
returned by:func:`__array__`. This practice will return ``TypeError``.
321332

322333
.. _matrix-objects:
323334

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -514,8 +514,9 @@ From other objects
514514
PyObject* op, PyArray_Descr* dtype, PyObject* context)
515515
516516
Return an ndarray object from a Python object that exposes the
517-
:obj:`~numpy.class.__array__` method. The :obj:`~numpy.class.__array__`
518-
method can take 0, or 1 argument ``([dtype])``. ``context`` is unused.
517+
:obj:`~numpy.class.__array__` method. The third-party implementations of
518+
:obj:`~numpy.class.__array__` must take ``dtype`` and ``copy`` keyword
519+
arguments. ``context`` is unused.
519520
520521
.. c:function:: PyObject* PyArray_ContiguousFromAny( \
521522
PyObject* op, int typenum, int min_depth, int max_depth)

‎doc/source/user/basics.dispatch.rst‎

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ example that has rather narrow utility but illustrates the concepts involved.
2222
...self._i= value
2323
...def__repr__(self):
2424
...returnf"{self.__class__.__name__}(N={self._N}, value={self._i})"
25-
...def__array__(self,dtype=None):
25+
...def__array__(self,dtype=None,copy=None):
2626
...returnself._i* np.eye(self._N,dtype=dtype)
2727

2828
Our custom array can be instantiated like:
@@ -84,7 +84,7 @@ For this example we will only handle the method ``__call__``
8484
...self._i= value
8585
...def__repr__(self):
8686
...returnf"{self.__class__.__name__}(N={self._N}, value={self._i})"
87-
...def__array__(self,dtype=None):
87+
...def__array__(self,dtype=None,copy=None):
8888
...returnself._i* np.eye(self._N,dtype=dtype)
8989
...def__array_ufunc__(self,ufunc,method,*inputs,**kwargs):
9090
...if method=='__call__':
@@ -135,7 +135,7 @@ conveniently by inheriting from the mixin
135135
...self._i= value
136136
...def__repr__(self):
137137
...returnf"{self.__class__.__name__}(N={self._N}, value={self._i})"
138-
...def__array__(self,dtype=None):
138+
...def__array__(self,dtype=None,copy=None):
139139
...returnself._i* np.eye(self._N,dtype=dtype)
140140
...def__array_ufunc__(self,ufunc,method,*inputs,**kwargs):
141141
...if method=='__call__':
@@ -173,7 +173,7 @@ functions to our custom variants.
173173
...self._i= value
174174
...def__repr__(self):
175175
...returnf"{self.__class__.__name__}(N={self._N}, value={self._i})"
176-
...def__array__(self,dtype=None):
176+
...def__array__(self,dtype=None,copy=None):
177177
...returnself._i* np.eye(self._N,dtype=dtype)
178178
...def__array_ufunc__(self,ufunc,method,*inputs,**kwargs):
179179
...if method=='__call__':
@@ -306,4 +306,3 @@ Refer to the `dask source code <https://github.com/dask/dask>`_ and
306306
examples of custom array containers.
307307

308308
See also:doc:`NEP 18<neps:nep-0018-array-function-protocol>`.
309-

‎doc/source/user/basics.interoperability.rst‎

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ relies on the existence of the following attributes or methods:
7575
- ``__array_interface__``: a Python dictionary containing the shape, the
7676
element type, and optionally, the data buffer address and the strides of an
7777
array-like object;
78-
- ``__array__()``: a method returning the NumPy ndarray view of an array-like
79-
object;
78+
- ``__array__()``: a method returning the NumPy ndarraycopy or aview of an
79+
array-likeobject;
8080

8181
The ``__array_interface__`` attribute can be inspected directly:
8282

@@ -125,6 +125,16 @@ new ndarray object. This is not optimal, as coercing arrays into ndarrays may
125125
cause performance problems or create the need for copies and loss of metadata,
126126
as the original object and any attributes/behavior it may have had, is lost.
127127

128+
The signature of the method should be ``__array__(self, dtype=None, copy=None)``.
129+
If a passed ``dtype`` isn't ``None`` and different than the object's data type,
130+
a casting should happen to a specified type. If ``copy`` is ``None``, a copy
131+
should be made only if ``dtype`` argument enforces it. For ``copy=True``, a copy
132+
should always be made, where ``copy=False`` should raise an exception if a copy
133+
is needed.
134+
135+
If a class implements the old signature ``__array__(self)``, for ``np.array(a)``
136+
a warning will be raised saying that ``dtype`` and ``copy`` arguments are missing.
137+
128138
To see an example of a custom array implementation including the use of
129139
``__array__()``, see:ref:`basics.dispatch`.
130140

‎numpy/__init__.pyi‎

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,9 +1464,13 @@ class ndarray(_ArrayOrScalarCommon, Generic[_ShapeType, _DType_co]):
14641464
def__class_getitem__(self,item:Any)->GenericAlias: ...
14651465

14661466
@overload
1467-
def__array__(self,dtype:None= ...,/)->ndarray[Any,_DType_co]: ...
1467+
def__array__(
1468+
self,dtype:None= ...,/,*,copy:None|bool= ...
1469+
)->ndarray[Any,_DType_co]: ...
14681470
@overload
1469-
def__array__(self,dtype:_DType,/)->ndarray[Any,_DType]: ...
1471+
def__array__(
1472+
self,dtype:_DType,/,*,copy:None|bool= ...
1473+
)->ndarray[Any,_DType]: ...
14701474

14711475
def__array_ufunc__(
14721476
self,
@@ -3715,9 +3719,9 @@ class poly1d:
37153719
__hash__:ClassVar[None]# type: ignore
37163720

37173721
@overload
3718-
def__array__(self,t:None= ...)->NDArray[Any]: ...
3722+
def__array__(self,t:None= ...,copy:None|bool= ...)->NDArray[Any]: ...
37193723
@overload
3720-
def__array__(self,t:_DType)->ndarray[Any,_DType]: ...
3724+
def__array__(self,t:_DType,copy:None|bool= ...)->ndarray[Any,_DType]: ...
37213725

37223726
@overload
37233727
def__call__(self,val:_ScalarLike_co)->Any: ...

‎numpy/_core/_add_newdocs.py‎

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -807,12 +807,14 @@
807807
a default ``dtype`` that can represent the values (by applying promotion
808808
rules when necessary.)
809809
copy : bool, optional
810-
Iftrue (default), then the array data is copied.Otherwise, a copy
811-
will only be made if ``__array__`` returns a copy, if obj is a nested
812-
sequence, or if a copy is needed to satisfy any of the other
810+
If``True`` (default), then the array data is copied.If ``None``,
811+
a copywill only be made if ``__array__`` returns a copy, if obj is
812+
a nestedsequence, or if a copy is needed to satisfy any of the other
813813
requirements (``dtype``, ``order``, etc.). Note that any copy of
814814
the data is shallow, i.e., for arrays with object dtype, the new
815815
array will point to the same objects. See Examples for `ndarray.copy`.
816+
For ``False`` it raises a ``ValueError`` if a copy cannot be avoided.
817+
Default: ``True``.
816818
order : {'K', 'A', 'C', 'F'}, optional
817819
Specify the memory layout of the array. If object is not an array, the
818820
newly created array will be in C order (row major) unless 'F' is
@@ -828,7 +830,7 @@
828830
'F' F order F order
829831
===== ========= ===================================================
830832
831-
When ``copy=False`` and a copy is made for other reasons, the result is
833+
When ``copy=None`` and a copy is made for other reasons, the result is
832834
the same as if ``copy=True``, with some exceptions for 'A', see the
833835
Notes section. The default order is 'K'.
834836
subok : bool, optional
@@ -915,7 +917,7 @@
915917

916918
add_newdoc('numpy._core.multiarray','asarray',
917919
"""
918-
asarray(a, dtype=None, order=None, *, device=None, like=None)
920+
asarray(a, dtype=None, order=None, *, device=None,copy=None,like=None)
919921
920922
Convert the input to an array.
921923
@@ -939,6 +941,13 @@
939941
For Array-API interoperability only, so must be ``"cpu"`` if passed.
940942
941943
.. versionadded:: 2.0.0
944+
copy : bool, optional
945+
If ``True``, then the object is copied. If ``None`` then the object is
946+
copied only if needed, i.e. if ``__array__`` returns a copy, if obj
947+
is a nested sequence, or if a copy is needed to satisfy any of
948+
the other requirements (``dtype``, ``order``, etc.).
949+
For ``False`` it raises a ``ValueError`` if a copy cannot be avoided.
950+
Default: ``None``.
942951
${ARRAY_FUNCTION_LIKE}
943952
944953
.. versionadded:: 1.20.0
@@ -2934,11 +2943,15 @@
29342943

29352944
add_newdoc('numpy._core.multiarray','ndarray', ('__array__',
29362945
"""
2937-
a.__array__([dtype], /)
2946+
a.__array__([dtype], /, *, copy=None)
29382947
2939-
Returns either a new reference to self if dtype is not given or a new array
2940-
of provided data type if dtype is different from the current dtype of the
2941-
array.
2948+
For ``dtype`` parameter it returns either a new reference to self if
2949+
``dtype`` is not given or a new array of provided data type if ``dtype``
2950+
is different from the current data type of the array.
2951+
For ``copy`` parameter it returns a new reference to self if
2952+
``copy=False`` or ``copy=None`` and copying isn't enforced by ``dtype``
2953+
parameter. The method returns a new array for ``copy=True``, regardless of
2954+
``dtype`` parameter.
29422955
29432956
"""))
29442957

‎numpy/_core/_asarray.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def require(a, dtype=None, requirements=None, *, like=None):
123123
order='C'
124124
requirements.remove('C')
125125

126-
arr=array(a,dtype=dtype,order=order,copy=False,subok=subok)
126+
arr=array(a,dtype=dtype,order=order,copy=None,subok=subok)
127127

128128
forpropinrequirements:
129129
ifnotarr.flags[prop]:

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp