# workaround
function convert_it(read_only_numpy_arr::PyObject)
# See https://github.com/JuliaPy/PyCall.jl/blob/master/src/pyarray.jl#L14-L24
# instead of PyBUF_ND_STRIDED = Cint(PyBUF_WRITABLE | PyBUF_FORMAT | PyBUF_ND | PyBUF_STRIDES)
# See https://github.com/JuliaPy/PyCall.jl/blob/master/src/pybuffer.jl#L113
pybuf = PyBuffer(read_only_numpy_arr, PyCall.PyBUF_FORMAT | PyCall.PyBUF_ND | PyCall.PyBUF_STRIDES)
T, native_byteorder = PyCall.array_format(pybuf)
sz = size(pybuf)
strd = PyCall.strides(pybuf)
length(strd) == 0 && (sz = ())
N = length(sz)
isreadonly = pybuf.buf.readonly==1
info = PyCall.PyArray_Info{T,N}(native_byteorder, sz, strd, pybuf.buf.buf, isreadonly, pybuf)
# See https://github.com/JuliaPy/PyCall.jl/blob/master/src/pyarray.jl#L123-L126
PyCall.PyArray{T,N}(read_only_numpy_arr, info)
end
arr2 = convert_it(arr) # arr2 is a PyArray
@assert isa(arr2, PyArray)
@assert size(arr2) == (10,)
println(arr2)
Based on the above, it seems possible to fix the PyArray constructor to handle this case. Separately, it would be even more useful to automatically convert read-only numpy arrays into an Array (and do a copy).
Currently, a read-only numpy array is not converted into either an
Array
or aPyArray
automatically:Attempting to convert manually into a
PyArray
withPyArray(arr)
gives an error "buffer source array is read-only", which makes sense because https://github.com/JuliaPy/PyCall.jl/blob/master/src/pyarray.jl#L16 seems to be assuming the buffer is writeable (PyBUF_ND_STRIDED
impliesPyBUF_WRITABLE
). This seems like it could be considered a bug inPyArray
constructor, sincePyArray
does check for thereadonly
flag later in the constructor: https://github.com/JuliaPy/PyCall.jl/blob/master/src/pyarray.jl#L22I worked around this:
Based on the above, it seems possible to fix the
PyArray
constructor to handle this case. Separately, it would be even more useful to automatically convert read-only numpy arrays into anArray
(and do a copy).