Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions src/pybuffer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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

#############################################################################
15 changes: 15 additions & 0 deletions test/testpybuffer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down