# Handling PyArray in Generic Functions: how to use \`similar\` and \`copy\` correctly

**URL:** <https://discourse.julialang.org/t/handling-pyarray-in-generic-functions-how-to-use-similar-and-copy-correctly/118569>\
**Category:** General Usage\
**Tags:** pythoncall\
**Created:** [August 24, 2024, 5:09pm UTC](https://discourse.julialang.org/t/handling-pyarray-in-generic-functions-how-to-use-similar-and-copy-correctly/118569 "2024-08-24T17:09:17Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![mpf01](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mpf01/32/8221_2.png) [@mpf01](https://discourse.julialang.org/u/mpf01)\
**Post date:** [August 24, 2024, 5:09pm UTC](https://discourse.julialang.org/t/handling-pyarray-in-generic-functions-how-to-use-similar-and-copy-correctly/118569/1 "2024-08-24T17:09:17Z")

</div>

I’m working on making my functions generic to handle various types of arrays, including `PyArray` from `PythonCall.jl`. But I’ve encountered a problem with the `similar` function on `PyArray` types.

Here’s a simple example that highlights the problem:

```julia
using PythonCall

a = PyArray([1, 2])
b = similar(a)

function foo(a::V, b::V) where V<:AbstractArray
    (a, b)
end

foo(a, b) # fails

```

This call to `foo` generates the following error:

```julia
ERROR: MethodError: no method matching foo(::PyArray{Int64, 1, true, true, Int64}, ::Vector{Int64})

```

I initially discovered this issue while attempting to integrate a Julia package with Python using JuliaCall and calling a function of the form

```julia
bar(a::V; b::V=similar(a)) where V<:AbstractArray

```

My goal is to pass PyArray objects to my functions seamlessly, without needing to convert them to standard Array objects first. I’m glad for any suggestions. Thanks!

---

<div class="post-metadata">

**Author:** ![bertschi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bertschi/32/33462_2.png) [@bertschi](https://discourse.julialang.org/u/bertschi)\
**Post date:** [August 24, 2024, 5:31pm UTC](https://discourse.julialang.org/t/handling-pyarray-in-generic-functions-how-to-use-similar-and-copy-correctly/118569/2 "2024-08-24T17:31:43Z")

</div>

`similar` and `copy` do not (always) create arrays of the same type, i.e., the following also fails

```julia
a = view([1,2,3,4], 1:2)
b = similar(a)
foo(a, b)

```

A possible fix is to change the type signature of `foo` to `foo(a::AbstractVector, b::AbstractVector)`. Unless there is a specific reason, it is often not necessary to restrict both arguments to the very same array type `V`, instead of just being both abstract arrays.

---

<div class="post-metadata">

**Author:** ![mpf01](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mpf01/32/8221_2.png) [@mpf01](https://discourse.julialang.org/u/mpf01)\
**Post date:** [August 25, 2024, 6:10am UTC](https://discourse.julialang.org/t/handling-pyarray-in-generic-functions-how-to-use-similar-and-copy-correctly/118569/3 "2024-08-25T06:10:55Z")

</div>

Thanks for the clarification, @bertschi. I hadn’t realized this was expected behavior of `copy` and `similar`.

As you suggested, I relaxed the type constraints on the relevant methods, and now the call from Python works without converting to standard arrays. Success!
