Skip to content

Commit 6fac15c

Browse files
author
Christopher Doris
committed
remove reliance on PyMemoryView layout
1 parent a5b3925 commit 6fac15c

File tree

5 files changed

+52
-64
lines changed

5 files changed

+52
-64
lines changed

src/API/types.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@ struct PyArray{T,N,M,L,R} <: AbstractArray{T,N}
7272
size::NTuple{N,Int} # size of the array
7373
strides::NTuple{N,Int} # strides (in bytes) between elements
7474
py::Py # underlying python object
75-
handle::Py # the data in this array is valid as long as this handle is alive
75+
handle::Any # the data in this array is valid as long as this handle is alive
7676
function PyArray{T,N,M,L,R}(
7777
::Val{:new},
7878
ptr::Ptr{R},
7979
size::NTuple{N,Int},
8080
strides::NTuple{N,Int},
8181
py::Py,
82-
handle::Py,
82+
handle::Any,
8383
) where {T,N,M,L,R}
8484
T isa Type || error("T must be a Type")
8585
N isa Int || error("N must be an Int")

src/C/consts.jl

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -239,16 +239,6 @@ end
239239
internal::Ptr{Cvoid} = C_NULL
240240
end
241241

242-
@kwdef struct PyMemoryViewObject
243-
ob_base::PyVarObject = PyVarObject()
244-
mbuf::PyPtr = PyNULL
245-
hash::Py_hash_t = 0
246-
flags::Cint = 0
247-
exports::Py_ssize_t = 0
248-
view::Py_buffer = Py_buffer()
249-
weakreflist::PyPtr = PyNULL
250-
end
251-
252242
@kwdef struct PyTypeObject
253243
ob_base::PyVarObject = PyVarObject()
254244
name::Cstring = C_NULL

src/C/extras.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ Py_TypeCheckFast(o, f::Integer) = Base.GC.@preserve o PyType_IsSubtypeFast(Py_Ty
77

88
PyType_IsSubtypeFast(t, f::Integer) = Cint(!iszero(PyType_GetFlags(t) & f))
99

10-
PyMemoryView_GET_BUFFER(m) = Base.GC.@preserve m Ptr{Py_buffer}(UnsafePtr{PyMemoryViewObject}(asptr(m)).view)
11-
1210
PyType_CheckBuffer(t) = Base.GC.@preserve t begin
1311
o = Ref{PyObject}(PyObject(0, asptr(t)))
1412
PyObject_CheckBuffer(o)

src/JlWrap/io.jl

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -94,42 +94,38 @@ pyjl_handle_error_type(::typeof(pyjlbinaryio_readline), io, exc) =
9494
exc isa MethodError && exc.f === read ? pybuiltins.ValueError : PyNULL
9595

9696
function pyjlbinaryio_readinto(io::IO, b::Py)
97-
m = pybuiltins.memoryview(b)
98-
c = m.c_contiguous
99-
if !pytruth(c)
100-
pydel!(c)
101-
errset(pybuiltins.ValueError, "input buffer is not contiguous")
97+
buf = Ref{Py_buffer}()
98+
if PyObject_GetBuffer(b, buf, PyBUF_SIMPLE | PyBUF_WRITABLE) < 0
10299
return PyNULL
103100
end
104-
pydel!(c)
105-
buf = unsafe_load(C.PyMemoryView_GET_BUFFER(m))
106-
if buf.readonly != 0
107-
pydel!(m)
108-
errset(pybuiltins.ValueError, "output buffer is read-only")
109-
return PyNULL
101+
local nb
102+
ptr = buf[].buf
103+
len = buf[].len
104+
try
105+
data = unsafe_wrap(Array, Ptr{UInt8}(ptr), len)
106+
nb = readbytes!(io, data)
107+
finally
108+
PyBuffer_Release(buf)
110109
end
111-
data = unsafe_wrap(Array, Ptr{UInt8}(buf.buf), buf.len)
112-
nb = readbytes!(io, data)
113-
pydel!(m)
114110
return Py(nb)
115111
end
116112
pyjl_handle_error_type(::typeof(pyjlbinaryio_readinto), io, exc) =
117113
exc isa MethodError && exc.f === readbytes! ? pybuiltins.ValueError : PyNULL
118114

119115
function pyjlbinaryio_write(io::IO, b::Py)
120-
m = pybuiltins.memoryview(b)
121-
c = m.c_contiguous
122-
if !pytruth(c)
123-
pydel!(c)
124-
errset(pybuiltins.ValueError, "input buffer is not contiguous")
116+
buf = Ref{Py_buffer}()
117+
if PyObject_GetBuffer(b, buf, PyBUF_SIMPLE) < 0
125118
return PyNULL
126119
end
127-
pydel!(c)
128-
buf = unsafe_load(C.PyMemoryView_GET_BUFFER(m))
129-
data = unsafe_wrap(Array, Ptr{UInt8}(buf.buf), buf.len)
130-
write(io, data)
131-
pydel!(m)
132-
return Py(buf.len)
120+
ptr = buf[].buf
121+
len = buf[].len
122+
try
123+
data = unsafe_wrap(Array, Ptr{UInt8}(ptr), len)
124+
write(io, data)
125+
finally
126+
PyBuffer_Release(buf)
127+
end
128+
return Py(len)
133129
end
134130
pyjl_handle_error_type(::typeof(pyjlbinaryio_write), io, exc) =
135131
exc isa MethodError && exc.f === write ? pybuiltins.ValueError : PyNULL

src/Wrap/PyArray.jl

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ struct PyArraySource_ArrayInterface <: PyArraySource
187187
dict::Py
188188
ptr::Ptr{Cvoid}
189189
readonly::Bool
190-
handle::Py
190+
handle::Any
191191
end
192192
function PyArraySource_ArrayInterface(x::Py, d::Py = x.__array_interface__)
193193
# offset
@@ -202,14 +202,16 @@ function PyArraySource_ArrayInterface(x::Py, d::Py = x.__array_interface__)
202202
ptr = Ptr{Cvoid}(pyconvert(UInt, data[0]))
203203
readonly = pyconvert(Bool, data[1])
204204
pydel!(data)
205-
handle = Py((x, d))
205+
handle = (x, d)
206206
else
207-
memview = @py memoryview(data === None ? x : data)
208-
pydel!(data)
209-
buf = UnsafePtr(C.PyMemoryView_GET_BUFFER(memview))
210-
ptr = buf.buf[!]
211-
readonly = buf.readonly[] != 0
212-
handle = Py((x, memview))
207+
buf = Ref{C.Py_buffer}()
208+
if C.PyObject_GetBuffer(data === None ? x : data, buf, C.PyBUF_RECORDS) < 0
209+
pythrow()
210+
end
211+
finalizer(C.PyBuffer_Release, buf)
212+
ptr = buf[].buf
213+
readonly = buf[].readonly != 0
214+
handle = buf
213215
end
214216
PyArraySource_ArrayInterface(x, d, ptr, readonly, handle)
215217
end
@@ -525,13 +527,15 @@ end
525527

526528
struct PyArraySource_Buffer <: PyArraySource
527529
obj::Py
528-
memview::Py
529-
buf::C.UnsafePtr{C.Py_buffer}
530+
buf::Base.RefValue{C.Py_buffer}
530531
end
531532
function PyArraySource_Buffer(x::Py)
532-
memview = pybuiltins.memoryview(x)
533-
buf = C.UnsafePtr(C.PyMemoryView_GET_BUFFER(memview))
534-
PyArraySource_Buffer(x, memview, buf)
533+
buf = Ref{C.Py_buffer}()
534+
if C.PyObject_GetBuffer(x, buf, C.PyBUF_RECORDS) < 0
535+
pythrow()
536+
end
537+
finalizer(C.PyBuffer_Release, buf)
538+
PyArraySource_Buffer(x, buf)
535539
end
536540

537541
const PYARRAY_BUFFERFORMAT_TO_TYPE = let c = Utils.islittleendian() ? '<' : '>'
@@ -578,20 +582,20 @@ pyarray_bufferformat_to_type(fmt::String) = get(
578582
)
579583

580584
function pyarray_get_R(src::PyArraySource_Buffer)
581-
ptr = src.buf.format[]
582-
return ptr == C_NULL ? UInt8 : pyarray_bufferformat_to_type(String(ptr))
585+
ptr = src.buf[].format
586+
return ptr == C_NULL ? UInt8 : pyarray_bufferformat_to_type(unsafe_string(ptr))
583587
end
584588

585-
pyarray_get_ptr(src::PyArraySource_Buffer, ::Type{R}) where {R} = Ptr{R}(src.buf.buf[!])
589+
pyarray_get_ptr(src::PyArraySource_Buffer, ::Type{R}) where {R} = Ptr{R}(src.buf[].buf)
586590

587-
pyarray_get_N(src::PyArraySource_Buffer) = Int(src.buf.ndim[])
591+
pyarray_get_N(src::PyArraySource_Buffer) = Int(src.buf[].ndim)
588592

589593
function pyarray_get_size(src::PyArraySource_Buffer, ::Val{N}) where {N}
590-
size = src.buf.shape[]
594+
size = src.buf[].shape
591595
if size == C_NULL
592-
N == 0 ? () : N == 1 ? (Int(src.buf.len[]),) : @assert false
596+
N == 0 ? () : N == 1 ? (Int(src.buf[].len),) : @assert false
593597
else
594-
ntuple(i -> Int(size[i]), N)
598+
ntuple(i -> Int(unsafe_load(size, i)), N)
595599
end
596600
end
597601

@@ -601,18 +605,18 @@ function pyarray_get_strides(
601605
::Type{R},
602606
size::NTuple{N,Int},
603607
) where {N,R}
604-
strides = src.buf.strides[]
608+
strides = src.buf[].strides
605609
if strides == C_NULL
606-
itemsize = src.buf.shape[] == C_NULL ? 1 : src.buf.itemsize[]
610+
itemsize = src.buf[].shape == C_NULL ? 1 : src.buf[].itemsize
607611
Utils.size_to_cstrides(itemsize, size)
608612
else
609-
ntuple(i -> Int(strides[i]), N)
613+
ntuple(i -> Int(unsafe_load(strides, i)), N)
610614
end
611615
end
612616

613-
pyarray_get_M(src::PyArraySource_Buffer) = src.buf.readonly[] == 0
617+
pyarray_get_M(src::PyArraySource_Buffer) = src.buf[].readonly == 0
614618

615-
pyarray_get_handle(src::PyArraySource_Buffer) = src.memview
619+
pyarray_get_handle(src::PyArraySource_Buffer) = src.buf
616620

617621
# AbstractArray methods
618622

0 commit comments

Comments
 (0)