Repository: Suzhou-Tongyuan/jnumpy (language: python)

Issue:
Check the element type when casting julia array to python
https://github.com/Suzhou-Tongyuan/jnumpy/blob/65cea6cc6a750911ab2c1545d94af26008e7b240/TyPython/src/CPython.ORM.jl#L343

actually only `AbstractArray{<:Number}` could success, so:
```julia
function py_cast(::Type{Py}, o::T) where {T <: AbstractArray{<:Number}}
 ...
end
```


Discussion / hints:

Fix patch:
diff --git a/TyPython/src/CPython.Julia.jl b/TyPython/src/CPython.Julia.jl
index 47dd807..e5994b9 100644
--- a/TyPython/src/CPython.Julia.jl
+++ b/TyPython/src/CPython.Julia.jl
@@ -71,24 +71,31 @@ function get_typekind(_::Union{ComplexF16, ComplexF32, ComplexF64})
     return Cchar('c')
 end
 
-function DynamicArray(x::TArray) where TArray<:AbstractArray
-    et = eltype(TArray)
-    typekind = get_typekind(zero(et))
-    if x isa LinearAlgebra.Transpose && parent(x) isa StridedArray
-        return LinearAlgebra.transpose(DynamicArray(LinearAlgebra.transpose(x)))
-    elseif x isa PermutedDimsArray && parent(x) isa StridedArray
-        return permutedims(DynamicArray(parent(x)), get_perm(x))
-    end
-    is_c_style = false
-    is_f_style = true
+function _normalized_array(x::AbstractArray, is_f_style)
     normalized_x = if x isa Array
         x
     elseif x isa StridedArray && x isa SubArray
         is_f_style = Base.iscontiguous(x)
         x
+    elseif x isa StridedArray && x isa Base.ReinterpretArray && parent(x) isa Array
+        x
     else
         collect(x)
     end
+    return normalized_x, is_f_style
+end
+
+function DynamicArray(x::AbstractArray)
+    et = eltype(x)
+    typekind = get_typekind(zero(et))
+    if x isa LinearAlgebra.Transpose && parent(x) isa StridedArray
+        return LinearAlgebra.transpose(DynamicArray(LinearAlgebra.transpose(x)))
+    elseif x isa PermutedDimsArray && parent(x) isa StridedArray
+        return permutedims(DynamicArray(parent(x)), get_perm(x))
+    end
+    is_c_style = false
+    is_f_style = true
+    normalized_x, is_f_style = _normalized_array(x, is_f_style)
     shape = collect(Py_ssize_t, size(normalized_x))
     ptr = reinterpret(Ptr{Cvoid}, pointer(normalized_x))
     ndim = convert(Cint, ndims(normalized_x))
@@ -160,7 +167,7 @@ end
     py_coerce(::Type{Py}, xs::AbstractArray)
 
 Convert julia array to numpy ndarray.
-Array, Transpose of Array, PermutedDimsArray of Array and some SubArray could be converted to ndarray without copy,
+Array, Transpose of Array, PermutedDimsArray of Array and some SubArray/ReinterpretArray could be converted to ndarray without copy,
 other arrays will first be copied with `collect()`, then converted to ndarray.
 """
 function py_coerce(::Type{Py}, @nospecialize(xs::AbstractArray))
diff --git a/TyPython/src/CPython.ORM.jl b/TyPython/src/CPython.ORM.jl
index d3c2bfb..1d7060b 100644
--- a/TyPython/src/CPython.ORM.jl
+++ b/TyPython/src/CPython.ORM.jl
@@ -340,6 +340,6 @@ function py_cast(::Type{Py}, o::Py)
     return o
 end
 
-function py_cast(::Type{Py}, o::T) where T <: AbstractArray
+function py_cast(::Type{Py}, o::T) where {T <: AbstractArray{<:Number}}
     py_coerce(Py, o)
 end


Test patch:
diff --git a/TyPython/test/convert.jl b/TyPython/test/convert.jl
index a421704..712698c 100644
--- a/TyPython/test/convert.jl
+++ b/TyPython/test/convert.jl
@@ -172,6 +172,19 @@ end
         py_f = py_cast(Py, f)
         @test py_f.dtype == np.dtype(py_cast(Py, "bool"))
     end
+    @testset "SubArray and ReinterpretArray" begin
+        x = rand(4, 4)
+        x_sub = @view x[2:4, :]
+        py_x_sub = py_cast(Py, x_sub)
+        @test py_cast(Tuple{Int, Int}, py_x_sub.shape) == (3, 4)
+        @test py_cast(Float64, py_x_sub[py_cast(Py, (0,0))]) == x_sub[1, 1]
+        @test !py_cast(Bool, py_x_sub.flags.c_contiguous)
+        @test !py_cast(Bool, py_x_sub.flags.f_contiguous)
+        x_re = reinterpret(ComplexF64, x)
+        py_x_re = py_cast(Py, x_re)
+        @test py_cast(Tuple{Int, Int}, py_x_re.shape) == (2, 4)
+        @test pointer(py_cast(Array, py_x_re)) == pointer(x)
+    end
     @test_throws CPython.PyException py_cast(Array, py_cast(Py, "abc"))
 end