diff --git a/CHANGELOG.md b/CHANGELOG.md index 572fd21c78f..9f21d433200 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ Also, that release drops support for Python 3.9, making Python 3.10 the minimum * Added implementation of `dpnp.ndarray.tofile` method [#2635](https://github.com/IntelPython/dpnp/pull/2635) * Extended `pre-commit` configuration with `pyupgrade`, `actionlint`, and `gersemi` hooks [#2658](https://github.com/IntelPython/dpnp/pull/2658) * Added implementation of `dpnp.ndarray.tobytes` method [#2656](https://github.com/IntelPython/dpnp/pull/2656) +* Added implementation of `dpnp.ndarray.__format__` method [#2662](https://github.com/IntelPython/dpnp/pull/2662) ### Changed diff --git a/doc/reference/ndarray.rst b/doc/reference/ndarray.rst index 321f2fe95b9..09d60a307b0 100644 --- a/doc/reference/ndarray.rst +++ b/doc/reference/ndarray.rst @@ -449,3 +449,4 @@ String representations: ndarray.__str__ ndarray.__repr__ + ndarray.__format__ diff --git a/dpnp/dpnp_array.py b/dpnp/dpnp_array.py index 219b88d105b..3e747f00ee4 100644 --- a/dpnp/dpnp_array.py +++ b/dpnp/dpnp_array.py @@ -302,7 +302,9 @@ def __floordiv__(self, other, /): r"""Return :math:`\text{self // value}`.""" return dpnp.floor_divide(self, other) - # '__format__', + def __format__(self, format_spec): + r"""Return :math:`\text{format(self, format_spec)}`.""" + return format(self.asnumpy(), format_spec) def __ge__(self, other, /): r"""Return :math:`\text{self >= value}`.""" diff --git a/dpnp/tests/test_ndarray.py b/dpnp/tests/test_ndarray.py index 7b334ddbd97..c7e9dc65b99 100644 --- a/dpnp/tests/test_ndarray.py +++ b/dpnp/tests/test_ndarray.py @@ -108,6 +108,21 @@ def test_strides(self): assert xp.full_like(a, fill_value=6) not in a +class TestFormat: + def test_basic(self): + a = numpy.array(3.14159) + ia = dpnp.array(a) + + spec = ".3f" + assert_equal(format(ia, spec), format(a, spec)) + + @pytest.mark.parametrize("xp", [dpnp, numpy]) + def test_1d(self, xp): + a = xp.array([3.14159]) + with pytest.raises(TypeError, match="unsupported format string"): + _ = format(a, ".2f") + + class TestToBytes: @pytest.mark.parametrize("order", ["C", "F", "K", "A", None]) def test_roundtrip_binary_str(self, order): diff --git a/dpnp/tests/third_party/cupy/core_tests/test_ndarray.py b/dpnp/tests/third_party/cupy/core_tests/test_ndarray.py index c7afd483e59..6f79a6a231f 100644 --- a/dpnp/tests/third_party/cupy/core_tests/test_ndarray.py +++ b/dpnp/tests/third_party/cupy/core_tests/test_ndarray.py @@ -1,3 +1,5 @@ +from __future__ import annotations + import copy import unittest @@ -649,21 +651,23 @@ def test_size_zero_dim_array_with_axis(self): xp.size(x, 0) -@pytest.mark.skip("python interface is not supported") class TestPythonInterface(unittest.TestCase): + @pytest.mark.skip("__bytes__ is not supported") @testing.for_all_dtypes() @testing.numpy_cupy_equal() def test_bytes_tobytes(self, xp, dtype): x = testing.shaped_arange((3, 4, 5), xp, dtype) return bytes(x) + @pytest.mark.skip("__bytes__ is not supported") @testing.for_all_dtypes() @testing.numpy_cupy_equal() def test_bytes_tobytes_empty(self, xp, dtype): x = xp.empty((0,), dtype) return bytes(x) + @pytest.mark.skip("__bytes__ is not supported") @testing.for_all_dtypes() @testing.numpy_cupy_equal() def test_bytes_tobytes_empty2(self, xp, dtype): @@ -674,6 +678,7 @@ def test_bytes_tobytes_empty2(self, xp, dtype): # if scalar is of an integer dtype including bool_. It's spec is # bytes(int): bytes object of size given by the parameter initialized with # null bytes. + @pytest.mark.skip("__bytes__ is not supported") @testing.for_float_dtypes() @testing.numpy_cupy_equal() def test_bytes_tobytes_scalar_array(self, xp, dtype):