diff --git a/src/pybuffer.jl b/src/pybuffer.jl index 5a25805b..125504b5 100644 --- a/src/pybuffer.jl +++ b/src/pybuffer.jl @@ -227,31 +227,35 @@ function array_format(pybuf::PyBuffer) # TODO: handle more cases: https://www.python.org/dev/peps/pep-3118/#additions-to-the-struct-string-syntax # refs: https://github.com/numpy/numpy/blob/v1.14.2/numpy/core/src/multiarray/buffer.c#L966 # https://github.com/numpy/numpy/blob/v1.14.2/numpy/core/_internal.py#L490 - # https://docs.python.org/2/library/struct.html#byte-order-size-and-alignment + # https://docs.python.org/3/library/struct.html#byte-order-size-and-alignment # "NULL implies standard unsigned bytes ("B")" --pep 3118 pybuf.buf.format == C_NULL && return UInt8, true fmt_str = get_format_str(pybuf) native_byteorder = true + use_native_sizes = true type_start_idx = 1 - typestrs = standard_typestrs if length(fmt_str) > 1 type_start_idx = 2 - if fmt_str[1] == '=' + if fmt_str[1] == '@' || fmt_str[1] == '^' + # defaults to native_byteorder: true, use_native_sizes: true elseif fmt_str[1] == '<' native_byteorder = ENDIAN_BOM == 0x04030201 + use_native_sizes = false elseif fmt_str[1] == '>' || fmt_str =='!' native_byteorder = ENDIAN_BOM == 0x01020304 - elseif fmt_str[1] == '@' || fmt_str[1] == '^' - typestrs = native_typestrs + use_native_sizes = false + elseif fmt_str[1] == '=' + use_native_sizes = false elseif fmt_str[1] == "Z" type_start_idx = 1 else error("Unsupported format string: \"$fmt_str\"") end end - typestrs[fmt_str[type_start_idx:end]], native_byteorder + strs2types = use_native_sizes ? native_typestrs : standard_typestrs + strs2types[fmt_str[type_start_idx:end]], native_byteorder end ############################################################################# diff --git a/test/testpybuffer.jl b/test/testpybuffer.jl index 8d735a05..f471c371 100644 --- a/test/testpybuffer.jl +++ b/test/testpybuffer.jl @@ -35,6 +35,21 @@ pyutf8(s::String) = pyutf8(PyObject(s)) @test_throws ArgumentError PyArray(wrong_endian_arr) end + @testset "dtype should match eltype" begin + npy2jl = Dict("int32"=>Int32, "float32"=>Float32, + "int64"=>Int64, "float64"=>Float64) + for (pytype, jltype) in npy2jl + @testset "dtype $pytype should match eltype $jltype" begin + jlarr = jltype[1:10;] + nparr = arrpyo(jlarr, dtype=pytype) + @test pystr(nparr["dtype"]) == pytype + jlarr2 = convert(PyAny, nparr) + @test eltype(jlarr2) == jltype + @test jlarr2 == jlarr + end + end + end + @testset "NoCopyArray 1d" begin ao = arrpyo(1.0:10.0, "d") pybuf = PyBuffer(ao, PyBUF_ND_CONTIGUOUS)