Skip to content

Commit 34e707f

Browse files
committed
lose outdated buffers.pxd
use simpler memoryvew APIs, now exposed by Cython itself
1 parent 63df4ab commit 34e707f

File tree

3 files changed

+41
-258
lines changed

3 files changed

+41
-258
lines changed

tests/test_socket.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import sys
1111
import time
1212
import warnings
13+
from array import array
1314
from unittest import mock
1415

1516
import pytest
@@ -468,10 +469,11 @@ def test_recv_into(self):
468469
a.send_multipart(msg)
469470

470471
# default nbytes: fits in array
471-
buf = bytearray(10)
472+
# make sure itemsize > 1 is handled right
473+
buf = array('Q', [0])
472474
nbytes = b.recv_into(buf)
473475
assert nbytes == len(msg[0])
474-
assert buf[:nbytes] == msg[0]
476+
assert buf.tobytes()[:nbytes] == msg[0]
475477

476478
# default nbytes: truncates to sizeof(buf)
477479
buf = bytearray(4)
@@ -500,7 +502,8 @@ def test_recv_into(self):
500502

501503
def test_recv_into_bad(self):
502504
a, b = self.create_bound_pair()
503-
b.rcvtimeo = 1000
505+
if not self.green:
506+
b.rcvtimeo = 1000
504507

505508
# bad calls
506509

zmq/backend/cython/_zmq.py

+35-21
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
PyBytes_Size,
6363
PyErr_CheckSignals,
6464
)
65+
from cython.cimports.cpython.buffer import Py_buffer, PyBuffer_IsContiguous
6566
from cython.cimports.cpython.memoryview import PyMemoryView_GET_BUFFER
6667
from cython.cimports.libc.errno import EAGAIN, EINTR, ENAMETOOLONG, ENOENT, ENOTSOCK
6768

@@ -141,7 +142,6 @@
141142
)
142143
from cython.cimports.zmq.backend.cython.libzmq import zmq_errno as _zmq_errno
143144
from cython.cimports.zmq.backend.cython.libzmq import zmq_poll as zmq_poll_c
144-
from cython.cimports.zmq.utils.buffers import asbuffer_r
145145

146146
import zmq
147147
from zmq.constants import SocketOption, _OptType
@@ -247,6 +247,18 @@ def _copy_zmq_msg_bytes(zmq_msg: pointer(zmq_msg_t)) -> bytes:
247247
return PyBytes_FromStringAndSize(data_c, data_len_c)
248248

249249

250+
@cfunc
251+
@inline
252+
def _asbuffer(buf, data_c: pointer(p_void)) -> size_t:
253+
"""Get a C buffer from a memoryview"""
254+
view = memoryview(buf)
255+
pybuf: pointer(Py_buffer) = PyMemoryView_GET_BUFFER(view)
256+
if not PyBuffer_IsContiguous(pybuf, 'A'):
257+
raise BufferError("memoryview: underlying buffer is not contiguous")
258+
data_c[0] = pybuf.buf
259+
return pybuf.len
260+
261+
250262
_gc = None
251263

252264

@@ -288,7 +300,7 @@ def __init__(
288300
self._failed_init = False
289301
return
290302

291-
asbuffer_r(data, cast(pointer(p_void), address(data_c)), address(data_len_c))
303+
data_len_c = _asbuffer(data, cast(pointer(p_void), address(data_c)))
292304

293305
# copy unspecified, apply copy_threshold
294306
if copy is None:
@@ -1193,7 +1205,12 @@ def recv(self, flags=0, copy: bint = True, track: bint = False):
11931205
return _recv_copy(self.handle, flags)
11941206
else:
11951207
frame = _recv_frame(self.handle, flags, track)
1196-
frame.more = self.get(zmq.RCVMORE)
1208+
more: bint = False
1209+
sz: size_t = sizeof(bint)
1210+
_getsockopt(
1211+
self.handle, ZMQ_RCVMORE, cast(p_void, address(more)), address(sz)
1212+
)
1213+
frame.more = more
11971214
return frame
11981215

11991216
def recv_into(self, buffer, /, *, nbytes=0, flags=0) -> C.int:
@@ -1238,22 +1255,20 @@ def recv_into(self, buffer, /, *, nbytes=0, flags=0) -> C.int:
12381255
"""
12391256
c_flags: C.int = flags
12401257
_check_closed(self)
1241-
view = memoryview(buffer)
1242-
if not view.contiguous:
1243-
raise ValueError("Can only recv_into contiguous buffers")
1244-
if nbytes < 0:
1258+
c_nbytes: C.int = nbytes
1259+
if c_nbytes < 0:
12451260
raise ValueError(f"{nbytes=} must be non-negative")
1246-
view_bytes: size_t = view.nbytes
1247-
c_nbytes: size_t = nbytes
1248-
if nbytes == 0:
1249-
c_nbytes = view_bytes
1250-
elif c_nbytes > view_bytes:
1251-
raise ValueError(f"{nbytes=} too big for memoryview of {view_bytes}B")
1252-
1261+
view = memoryview(buffer)
12531262
# get C buffer
1254-
py_buf = PyMemoryView_GET_BUFFER(view)
1263+
py_buf: pointer(Py_buffer) = PyMemoryView_GET_BUFFER(view)
12551264
if py_buf.readonly:
12561265
raise ValueError("Cannot recv_into readonly buffer")
1266+
if not PyBuffer_IsContiguous(py_buf, 'A'):
1267+
raise ValueError("Can only recv_into contiguous buffer")
1268+
if nbytes == 0:
1269+
c_nbytes = py_buf.len
1270+
elif c_nbytes > py_buf.len:
1271+
raise ValueError(f"{nbytes=} too big for memoryview of {py_buf.len}B")
12571272

12581273
# call zmq_recv, with retries
12591274
while True:
@@ -1391,11 +1406,10 @@ def _send_copy(handle: p_void, buf, flags: C.int = 0):
13911406
"""Send a message on this socket by copying its content."""
13921407
rc: C.int
13931408
msg = declare(zmq_msg_t)
1394-
c_bytes = declare(p_char)
1395-
c_bytes_len: Py_ssize_t = 0
1409+
c_bytes = declare(p_void)
13961410

13971411
# copy to c array:
1398-
asbuffer_r(buf, cast(pointer(p_void), address(c_bytes)), address(c_bytes_len))
1412+
c_bytes_len = _asbuffer(buf, address(c_bytes))
13991413

14001414
# Copy the msg before sending. This avoids any complications with
14011415
# the GIL, etc.
@@ -1976,21 +1990,21 @@ def monitored_queue(
19761990
in_msg = declare(zmq_msg_t)
19771991
out_msg = declare(zmq_msg_t)
19781992
swap_ids: bint
1979-
msg_c: p_char = NULL
1993+
msg_c: p_void = NULL
19801994
msg_c_len = declare(Py_ssize_t)
19811995
rc: C.int
19821996

19831997
# force swap_ids if both ROUTERs
19841998
swap_ids = in_socket.type == ZMQ_ROUTER and out_socket.type == ZMQ_ROUTER
19851999

19862000
# build zmq_msg objects from str prefixes
1987-
asbuffer_r(in_prefix, cast(pointer(p_void), address(msg_c)), address(msg_c_len))
2001+
msg_c_len = _asbuffer(in_prefix, address(msg_c))
19882002
rc = zmq_msg_init_size(address(in_msg), msg_c_len)
19892003
_check_rc(rc)
19902004

19912005
memcpy(zmq_msg_data(address(in_msg)), msg_c, zmq_msg_size(address(in_msg)))
19922006

1993-
asbuffer_r(out_prefix, cast(pointer(p_void), address(msg_c)), address(msg_c_len))
2007+
msg_c_len = _asbuffer(out_prefix, address(msg_c))
19942008

19952009
rc = zmq_msg_init_size(address(out_msg), msg_c_len)
19962010
_check_rc(rc)

zmq/utils/buffers.pxd

-234
This file was deleted.

0 commit comments

Comments
 (0)