Repository: ivy-llc/ivy

Issue:
copyto



Discussion:

Resolving patch:
diff --git a/ivy/functional/frontends/numpy/manipulation_routines/basic_operations.py b/ivy/functional/frontends/numpy/manipulation_routines/basic_operations.py
--- a/ivy/functional/frontends/numpy/manipulation_routines/basic_operations.py
+++ b/ivy/functional/frontends/numpy/manipulation_routines/basic_operations.py
@@ -1,6 +1,41 @@
 # local
 import ivy
-from ivy.functional.frontends.numpy.func_wrapper import inputs_to_ivy_arrays
+from ivy.functional.frontends.numpy.func_wrapper import (
+    inputs_to_ivy_arrays,
+    _assert_no_array,
+    _assert_array,
+)
+
+
+@inputs_to_ivy_arrays
+def copyto(dst, src, /, *, casting="same_kind", where=True):
+    # Handle casting
+    # Numpy copyto doesn't cast the inputs
+    # It just checks casting rules
+    ivy.utils.assertions.check_elem_in_list(
+        casting,
+        ["no", "equiv", "safe", "same_kind", "unsafe"],
+        message="casting must be one of [no, equiv, safe, same_kind, unsafe]",
+    )
+
+    args = [dst, src]
+    args_idxs = ivy.nested_argwhere(args, ivy.is_array)
+    args_to_check = ivy.multi_index_nest(args, args_idxs)
+    dtype = args_to_check[0].dtype
+
+    if casting in ["no", "equiv"]:
+        _assert_no_array(
+            args_to_check,
+            dtype,
+        )
+    elif casting in ["same_kind", "safe"]:
+        _assert_array(
+            args_to_check,
+            dtype,
+            casting=casting,
+        )
+
+    ivy.where(where, src, dst, out=dst)
 
 
 @inputs_to_ivy_arrays


Test patch:
diff --git a/ivy_tests/test_ivy/test_frontends/test_numpy/test_manipulation_routines/test_basic_operations.py b/ivy_tests/test_ivy/test_frontends/test_numpy/test_manipulation_routines/test_basic_operations.py
--- a/ivy_tests/test_ivy/test_frontends/test_numpy/test_manipulation_routines/test_basic_operations.py
+++ b/ivy_tests/test_ivy/test_frontends/test_numpy/test_manipulation_routines/test_basic_operations.py
@@ -1,11 +1,59 @@
 # global
 from hypothesis import strategies as st
+import ivy
+import ivy.functional.frontends.numpy as ivy_np
+import numpy as np
 
 # local
 import ivy_tests.test_ivy.helpers as helpers
+import ivy_tests.test_ivy.test_frontends.test_numpy.helpers as np_frontend_helpers
 from ivy_tests.test_ivy.helpers import handle_frontend_test
 
 
+@st.composite
+def generate_copyto_args(draw):
+    input_dtypes, xs, casting, _ = draw(np_frontend_helpers.dtypes_values_casting_dtype(
+        arr_func=[
+            lambda: helpers.dtype_and_values(
+                available_dtypes=helpers.get_dtypes("valid"),
+                num_arrays=2,
+                shared_dtype=True,
+                min_num_dims=1,
+            )
+        ],
+    ))
+    where = draw(np_frontend_helpers.where(shape=xs[0].shape))
+    return input_dtypes, xs, casting, where
+
+
+# copyto
+@handle_frontend_test(
+    fn_tree="numpy.copyto",
+    test_with_out=st.just(False),
+    copyto_args=generate_copyto_args()
+)
+def test_numpy_copyto(
+    copyto_args,
+):
+    _, xs, casting, where = copyto_args
+    if isinstance(where, list) or isinstance(where, tuple):
+        where = where[0]
+        
+    src_ivy = ivy_np.array(xs[0])
+    dst_ivy = ivy_np.array(xs[1])
+    ivy_np.copyto(dst_ivy, src_ivy, where=where, casting=casting)
+
+    src_np = np.array(xs[0])
+    dst_np = np.array(xs[1])
+    np.copyto(dst_np, src_np, where=where, casting=casting)
+
+    assert dst_np.shape == dst_ivy.shape
+    # value test
+    dst_ = ivy.to_numpy(dst_ivy.ivy_array)
+    helpers.assert_all_close(dst_, dst_np)
+    assert id(src_ivy) != id(dst_ivy)
+
+
 # shape
 @handle_frontend_test(
     fn_tree="numpy.shape",