Skip to content

Commit 84817ef

Browse files
committed
Merge pull request ipython#7798 from jasongrout/buffer-memoryview
Extract session buffers as memoryviews
2 parents 454aa2c + 4abb13b commit 84817ef

3 files changed

Lines changed: 14 additions & 7 deletions

File tree

IPython/html/base/zmqhandlers.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import json
99
import struct
1010
import warnings
11+
import sys
1112

1213
try:
1314
from urllib.parse import urlparse # Py 3
@@ -43,6 +44,8 @@ def serialize_binary_message(msg):
4344
# don't modify msg or buffer list in-place
4445
msg = msg.copy()
4546
buffers = list(msg.pop('buffers'))
47+
if sys.version_info < (3, 4):
48+
buffers = [x.tobytes() for x in buffers]
4649
bmsg = json.dumps(msg, default=date_default).encode('utf8')
4750
buffers.insert(0, bmsg)
4851
nbufs = len(buffers)

IPython/html/tests/test_serialize.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,14 @@
1313
def test_serialize_binary():
1414
s = Session()
1515
msg = s.msg('data_pub', content={'a': 'b'})
16-
msg['buffers'] = [ os.urandom(3) for i in range(3) ]
16+
msg['buffers'] = [ memoryview(os.urandom(3)) for i in range(3) ]
1717
bmsg = serialize_binary_message(msg)
1818
nt.assert_is_instance(bmsg, bytes)
1919

2020
def test_deserialize_binary():
2121
s = Session()
2222
msg = s.msg('data_pub', content={'a': 'b'})
23-
msg['buffers'] = [ os.urandom(2) for i in range(3) ]
23+
msg['buffers'] = [ memoryview(os.urandom(2)) for i in range(3) ]
2424
bmsg = serialize_binary_message(msg)
2525
msg2 = deserialize_binary_message(bmsg)
2626
nt.assert_equal(msg2, msg)

IPython/kernel/zmq/session.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -810,18 +810,19 @@ def deserialize(self, msg_list, content=True, copy=True):
810810
Whether to unpack the content dict (True), or leave it packed
811811
(False).
812812
copy : bool (True)
813-
Whether to return the bytes (True), or the non-copying Message
814-
object in each place (False).
813+
Whether msg_list contains bytes (True) or the non-copying Message
814+
objects in each place (False).
815815
816816
Returns
817817
-------
818818
msg : dict
819819
The nested message dict with top-level keys [header, parent_header,
820-
content, buffers].
820+
content, buffers]. The buffers are returned as memoryviews.
821821
"""
822822
minlen = 5
823823
message = {}
824824
if not copy:
825+
# pyzmq didn't copy the first parts of the message, so we'll do it
825826
for i in range(minlen):
826827
msg_list[i] = msg_list[i].bytes
827828
if self.auth is not None:
@@ -846,8 +847,11 @@ def deserialize(self, msg_list, content=True, copy=True):
846847
message['content'] = self.unpack(msg_list[4])
847848
else:
848849
message['content'] = msg_list[4]
849-
850-
message['buffers'] = msg_list[5:]
850+
buffers = [memoryview(b) for b in msg_list[5:]]
851+
if buffers and buffers[0].shape is None:
852+
# force copy to workaround pyzmq #646
853+
buffers = [memoryview(b.bytes) for b in msg_list[5:]]
854+
message['buffers'] = buffers
851855
# adapt to the current version
852856
return adapt(message)
853857

0 commit comments

Comments
 (0)