Skip to content

Commit a0454a5

Browse files
committed
session.send(): Allow sending of bytes, str, or bytearray
In pynuodb 2.x we only accepted str here, then we changed it to accept only bytes. Instead allow users to send any of bytes, str, or bytearray. Add a test of the different types of send. Note, regardless of the type of message given to send(), recv() still always returns bytes.
1 parent ce1ba1d commit a0454a5

File tree

2 files changed

+36
-17
lines changed

2 files changed

+36
-17
lines changed

pynuodb/session.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
from urlparse import urlparse # type: ignore
2727

2828
try:
29-
from typing import Dict, Iterable, Mapping, Optional, Tuple # pylint: disable=unused-import
29+
from typing import Dict, Iterable, Mapping # pylint: disable=unused-import
30+
from typing import Optional, Tuple, Union # pylint: disable=unused-import
3031
except ImportError:
3132
pass
3233

@@ -394,19 +395,31 @@ def __constructServiceMessage(self,
394395
return message
395396

396397
def send(self, message):
397-
# type: (bytes) -> None
398-
"""Send an encoded message to the server over the socket."""
398+
# type: (Union[str, bytes, bytearray]) -> None
399+
"""Send an encoded message to the server over the socket.
400+
401+
The message to be sent is either already-encoded bytes or bytearray,
402+
or it's a UTF-8 str.
403+
"""
399404
sock = self._sock
405+
406+
if isinstance(message, bytearray):
407+
data = bytes(message)
408+
elif isinstance(message, bytes) or isP2:
409+
data = message # type: ignore
410+
elif isinstance(message, str):
411+
data = message.encode('utf-8')
412+
400413
if self.__cipherOut:
401-
message = self.__cipherOut.transform(message)
414+
data = self.__cipherOut.transform(data)
402415

403-
lenStr = struct.pack("!I", len(message))
416+
lenStr = struct.pack("!I", len(data))
404417

405418
try:
406419
# We should send this in two parts to avoid making a complete copy
407420
# of the message when we send it. But, I think the server may be
408421
# unhappy if it receives the length then has to wait for the data.
409-
sock.send(lenStr + message)
422+
sock.send(lenStr + data)
410423
except Exception:
411424
self.close()
412425
raise

tests/nuodb_service_test.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,24 @@ def test_query_memory(self):
2121
procs = ap_conn.get_processes(db_name=DATABASE_NAME)
2222
dbpasswd = ap_conn._get_db_password(DATABASE_NAME)
2323

24-
session = pynuodb.session.Session(
25-
procs[0].address, service='Query',
26-
options={'verifyHostname': 'False'})
27-
session.authorize('Cloud', dbpasswd)
24+
def try_message(msg):
25+
session = pynuodb.session.Session(
26+
procs[0].address, service='Query',
27+
options={'verifyHostname': 'False'})
28+
session.authorize('Cloud', dbpasswd)
29+
session.send(msg)
30+
res = session.recv()
31+
root = ET.fromstring(res)
32+
self.assertEqual(root.tag, 'MemoryInfo')
33+
info = root.findall('HeapInformation')
34+
self.assertEqual(len(info), 1)
35+
self.assertEqual(info[0].tag, 'HeapInformation')
2836

29-
session.send('<Request Service="Query" Type="Memory"/>'.encode('utf-8'))
30-
res = session.recv()
31-
root = ET.fromstring(res)
32-
self.assertEqual(root.tag, 'MemoryInfo')
33-
info = root.findall('HeapInformation')
34-
self.assertEqual(len(info), 1)
35-
self.assertEqual(info[0].tag, 'HeapInformation')
37+
# Send with different types of buffers
38+
msg = '<Request Service="Query" Type="Memory"/>'
39+
try_message(msg)
40+
try_message(msg.encode('utf-8'))
41+
try_message(pynuodb.crypt.bytesToArray(msg.encode('utf-8')))
3642

3743
def test_request_gc(self):
3844
"""Test a request operation."""

0 commit comments

Comments
 (0)