From d89b4ac88a8fac9fe2dbbd2eb326a6e443bb7ec4 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Tue, 4 Nov 2025 21:56:02 +0100 Subject: [PATCH 1/8] Add implementation of dpnp.ndarray.tolist method --- dpnp/dpnp_array.py | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/dpnp/dpnp_array.py b/dpnp/dpnp_array.py index beba058a998c..602a56bcbedb 100644 --- a/dpnp/dpnp_array.py +++ b/dpnp/dpnp_array.py @@ -2014,7 +2014,51 @@ def to_device(self, device, /, *, stream=None): # 'tobytes', # 'tofile', - # 'tolist', + + def tolist(self): + """ + Converts the array to a (possibly nested) Python list. + + For full documentation refer to :obj:`numpy.ndarray.tolist`. + + Returns + ------- + out : list + The possibly nested Python list of array elements. + + Examples + -------- + For a 1D array, ``a.tolist()`` is almost the same as ``list(a)``, + except that ``tolist`` changes 0-d arrays to Python scalars: + + >>> import numpy as np + >>> a = np.array([1, 2]) + >>> list(a) + [array(1), array(2)] + >>> a_tolist = a.tolist() + [1, 2] + + Additionally, for a 2D array, ``tolist`` applies recursively: + + >>> a = np.array([[1, 2], [3, 4]]) + >>> list(a) + [array([1, 2]), array([3, 4])] + >>> a.tolist() + [[1, 2], [3, 4]] + + The base case for this recursion is a 0D array: + + >>> a = np.array(1) + >>> list(a) + Traceback (most recent call last): + ... + TypeError: iteration over a 0-d array + >>> a.tolist() + 1 + + """ + + return self.asnumpy().tolist() def trace(self, offset=0, axis1=0, axis2=1, dtype=None, *, out=None): """ From 89f7cbaf3c4b666e4d48ace649beed46326260ee Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Tue, 4 Nov 2025 22:09:22 +0100 Subject: [PATCH 2/8] Enable third party tests --- .../third_party/cupy/logic_tests/test_type_test.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dpnp/tests/third_party/cupy/logic_tests/test_type_test.py b/dpnp/tests/third_party/cupy/logic_tests/test_type_test.py index ab1573a9b933..f4261a890f4c 100644 --- a/dpnp/tests/third_party/cupy/logic_tests/test_type_test.py +++ b/dpnp/tests/third_party/cupy/logic_tests/test_type_test.py @@ -1,9 +1,10 @@ +from __future__ import annotations + import unittest import numpy import pytest -import dpnp as cupy from dpnp.tests.third_party.cupy import testing @@ -122,7 +123,6 @@ def test_scalar(self, xp, dtype): @testing.for_all_dtypes() @testing.numpy_cupy_equal() def test_list(self, xp, dtype): - a = testing.shaped_arange((2, 3), xp, dtype) - if xp == cupy: - a = a.asnumpy() - return getattr(xp, self.func)(a.tolist()) + return getattr(xp, self.func)( + testing.shaped_arange((2, 3), xp, dtype).tolist() + ) From f1db9e818c1bd4a72b56103b5479d1ebc0098fe5 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Tue, 4 Nov 2025 22:21:23 +0100 Subject: [PATCH 3/8] Add more tests coverage --- dpnp/tests/test_ndarray.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/dpnp/tests/test_ndarray.py b/dpnp/tests/test_ndarray.py index ce857d73ea25..e8917b214e72 100644 --- a/dpnp/tests/test_ndarray.py +++ b/dpnp/tests/test_ndarray.py @@ -107,6 +107,16 @@ def test_strides(self): assert xp.full_like(a, fill_value=6) not in a +class TestToList: + @pytest.mark.parametrize( + "data", [[1, 2], [[1, 2], [3, 4]]], ids=["1d", "2d"] + ) + def test_1d(self, data): + a = numpy.array(data) + ia = dpnp.array(a) + assert_array_equal(ia.tolist(), a.tolist()) + + class TestView: def test_none_dtype(self): a = numpy.ones((1, 2, 4), dtype=numpy.int32) From e6ee50442cd2ca14e12826d445ddcbdf1feb7052 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Tue, 4 Nov 2025 22:38:00 +0100 Subject: [PATCH 4/8] Add io.rst page with Input and Output API references --- doc/reference/io.rst | 76 ++++++++++++++++++++++++++++++++++++++ doc/reference/routines.rst | 1 + 2 files changed, 77 insertions(+) create mode 100644 doc/reference/io.rst diff --git a/doc/reference/io.rst b/doc/reference/io.rst new file mode 100644 index 000000000000..b75159c92d32 --- /dev/null +++ b/doc/reference/io.rst @@ -0,0 +1,76 @@ +.. currentmodule:: dpnp + +Input and output +================ + +.. hint:: `NumPy API Reference: Input and output `_ + +.. NumPy binary files (npy, npz) +.. ----------------------------- +.. .. autosummary:: +.. :toctree: generated/ +.. :nosignatures: + +.. load +.. save +.. savez +.. savez_compressed +.. lib.npyio.NpzFile + +.. The format of these binary file types is documented in +.. :py:mod:`numpy.lib.format` + +Text files +---------- +.. autosummary:: + :toctree: generated/ + :nosignatures: + + loadtxt + savetxt + genfromtxt + fromregex + fromstring + ndarray.tofile + ndarray.tolist + +Raw binary files +---------------- + +.. autosummary:: + :toctree: generated/ + :nosignatures: + + fromfile + ndarray.tofile + +.. String formatting +.. ----------------- +.. .. autosummary:: +.. :toctree: generated/ +.. :nosignatures: + +.. array2string +.. array_repr +.. array_str +.. format_float_positional +.. format_float_scientific + +.. Text formatting options +.. ----------------------- +.. .. autosummary:: +.. :toctree: generated/ +.. :nosignatures: + +.. set_printoptions +.. get_printoptions +.. printoptions + +Base-n representations +---------------------- +.. autosummary:: + :toctree: generated/ + :nosignatures: + + binary_repr + base_repr diff --git a/doc/reference/routines.rst b/doc/reference/routines.rst index e38eb159fd32..e8013e134273 100644 --- a/doc/reference/routines.rst +++ b/doc/reference/routines.rst @@ -18,6 +18,7 @@ These functions cover a subset of exceptions fft functional + io indexing linalg logic From f148d7272f0207d063bcb4c55ec03bbcd2df1768 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Tue, 4 Nov 2025 22:39:07 +0100 Subject: [PATCH 5/8] Rename test --- dpnp/tests/test_ndarray.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dpnp/tests/test_ndarray.py b/dpnp/tests/test_ndarray.py index e8917b214e72..7aa7ac699e44 100644 --- a/dpnp/tests/test_ndarray.py +++ b/dpnp/tests/test_ndarray.py @@ -111,7 +111,7 @@ class TestToList: @pytest.mark.parametrize( "data", [[1, 2], [[1, 2], [3, 4]]], ids=["1d", "2d"] ) - def test_1d(self, data): + def test_basic(self, data): a = numpy.array(data) ia = dpnp.array(a) assert_array_equal(ia.tolist(), a.tolist()) From c6c83b4bc12d04887f60973475398b3bdf22de39 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Wed, 5 Nov 2025 12:56:05 +0100 Subject: [PATCH 6/8] Fix typo in the example text --- dpnp/dpnp_array.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dpnp/dpnp_array.py b/dpnp/dpnp_array.py index 602a56bcbedb..0b0c8c876ca0 100644 --- a/dpnp/dpnp_array.py +++ b/dpnp/dpnp_array.py @@ -2029,7 +2029,7 @@ def tolist(self): Examples -------- For a 1D array, ``a.tolist()`` is almost the same as ``list(a)``, - except that ``tolist`` changes 0-d arrays to Python scalars: + except that ``tolist`` changes 0D arrays to Python scalars: >>> import numpy as np >>> a = np.array([1, 2]) From 2580dfb62d4bfffa5a7a141a361c1c336bdc2e57 Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Wed, 5 Nov 2025 12:58:52 +0100 Subject: [PATCH 7/8] Add PR to the changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d4c45aa8d280..d7082b8f54fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ Also, that release drops support for Python 3.9, making Python 3.10 the minimum * Added implementation of `dpnp.scipy.special.erfcx` [#2596](https://github.com/IntelPython/dpnp/pull/2596) * Added implementation of `dpnp.scipy.special.erfinv` and `dpnp.scipy.special.erfcinv` [#2624](https://github.com/IntelPython/dpnp/pull/2624) * Enabled support of Python 3.14 [#2631](https://github.com/IntelPython/dpnp/pull/2631) +* Added implementation of `dpnp.ndarray.tolist` method [#2652](https://github.com/IntelPython/dpnp/pull/2652) ### Changed From c6b8bc79fb4c9e21cd7310f83455cda60c24d61c Mon Sep 17 00:00:00 2001 From: Anton Volkov Date: Wed, 5 Nov 2025 15:44:05 +0100 Subject: [PATCH 8/8] Fix typos in the examples --- dpnp/dpnp_array.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dpnp/dpnp_array.py b/dpnp/dpnp_array.py index 0b0c8c876ca0..e8902a77eb13 100644 --- a/dpnp/dpnp_array.py +++ b/dpnp/dpnp_array.py @@ -2031,11 +2031,11 @@ def tolist(self): For a 1D array, ``a.tolist()`` is almost the same as ``list(a)``, except that ``tolist`` changes 0D arrays to Python scalars: - >>> import numpy as np + >>> import dpnp as np >>> a = np.array([1, 2]) >>> list(a) [array(1), array(2)] - >>> a_tolist = a.tolist() + >>> a.tolist() [1, 2] Additionally, for a 2D array, ``tolist`` applies recursively: